进程的概念
进程就是正在执行中的的程序和其所使用资源的总称。
进程的特性
所有进程都是初始init进程
的后代,进程之间是树的结构关系。
进程线程的关系
在Linux内核中进程线程都使用进程描述符即并不严格区分二者,只是将线程视为某进程的子进程。
Linux如何存放和表示进程
内核通过名为进程描述符的结构表示进程,其结构类型是task_struct
。通过进程描述符组成名为task list任务队列
的双向循环链表。
每个task_struct
在32位机器上大约占1.7KB内存。
// linux/sched.h
struct task_struct{
unsigned long state;
int prio;
unsigned long policy;
struct task_struct *parent;
struct list_head tasks;
pid_t pid;
// ...
}
分配task_struct结构
内核通过slab分配器动态分配task_struct
,在每个内核栈的栈底创建一个thread_info
结构体,其中的task
存放指向实际指向task_struct
的指针。
// asm/thread_info.h
struct thread_info{
struct task_struct *task;
// ...
}
创建进程
- spawn == fork + exec族
写时拷贝
注意copy on write(写时拷贝)的优化思路:创建进程先使父子进程共享地址空间,只有到子进程需要写入时再拷贝。
fork()
vfork的缺陷(答书P28页的设想)
如果exec()调用失败,会导致死锁。
如何把新的执行映像装入地址空间*
exec()系统调用族
如何表示进程的层次关系*
想想树形结构
父进程如何收集后代的信息*
wait()系统调用
进程的消亡
调用exit()进程自己体面或帮进程体面
孤儿进程
父进程在该子进程之前终止,init
进程会成为子进程新的父进程,init
进程会清理掉僵尸进程。