在Linux中,进程(process)的概念不光指一个程序执行体,还包括了它的虚拟地址空间,打开的文件,未处理的信号等,可以说进程是一种资源的集合。
任务管理
进程创建
Linux中进程的创建沿用了传统Unix的做法,新的进程(称为“子进程”)由一个既有的进程(称为“父进程”)通过"fork"调用产生。
除了父进程的PID, page table和pending signals,子进程将共享父进程的几乎其他所有资源。因此,"fork"本身存在的开销主要是page table的复制和PID的申请。

父进程中属于"data"段的页面将被临时设置为read-only,并打上Copy-on-Write (COW)的标志。子进程有自己的page table,但和父进程共享页面。
直到子进程试图修改这些共享的页面,才会因为页面被标记为“只读”而触发page fault, 进而复制出一份新的页面。

"fork"完成后,父进程和子进程都将从"fork"返回,且都执行相同的程序。但不同的进程是需要做不同的事情的,如果子进程调用"exec",就表示接下来要独立运行了。
因为是在同一个节点返回,为了区分,"fork"调用为父进程和子进程返回了不同的值,返回0给子进程,返回子进程的PID给父进程。
子进程运行结束后,成为zombie进程,等待父进程来查询自己退出的原因,记录原因的变量通过"wait"函数的输出参数传递(并不等于子进程调用"exit"函数时的入参)。

进程描述
进程在Linux中由"task_struct"结构体来描述,以链表的形式组织,以方便内核的统一管理。

"task_struct"可以算是一个巨大的结构体,在2.6.34版本中,基于32位系统就要占据1.7KB的空间。这也不难理解,因为它几乎包含了关于一个process的全部信息。

这里仅列出其中的一小部分(定义在"/include/linux/sched.h"):
struct task_struct {
void *stack;
volatile long state;
pid_t pid;
pid_t tgid;
struct mm_struct *mm;
struct mm_struct *active_mm;
struct files_struct *files;...
}




