作为多任务操作系统,Linux管理着许多进程。在内核里面,进程的context由一个struct task_struct
表示,定义在头文件<linux/sched.h>
中。在内核中task既是进程,进程既是task。
task用pid标识,pid为1初始的init进程的task_struct
时是静态分配的,叫做init_task
。
linux提供了一个C语言的宏current
用来获取当前task的task_struct
,current
的实现是CPU相关的。
task_struct
作为可以运行的实体,它的运行时状态由state
属性表示,TASK_RUNNING
表示task处于可运行状态,可用set_task_state(task, state)
来更改。task的终止状态由exit_state
表示,EXIT_DEAD
表示task死亡。
在tasks管理方面,首先所有的tasks构成一个环形链表,task_struct
的tasks
属性是该链表的节点,可以用以下方法遍历tasks:
此外,tasks又以树形的方式组织,属性parent
, children
, sibling
用于此目的。
LKD(Linux内核设计与实现)
- Chapter 3 Process Management
Linux头文件
<linux/sched.h>
机制:
- pid的最大值可以由
/proc/sys/kernel/pid_max
控制,默认是32768。
实现:
- 进程由
fork()
创建,代码在kernel/fork.c
。 fork()
具有Copy-on-write以及Child-runs-first等语义。vfork
和fork
略有不同,vfork
不拷贝page table,父进程阻塞直到子进程退出或者执行execve()
。- 当父进程先于子进程退出时,kernel要为子进程重新找一个父进程,相关的函数是
find_new_reaper()
和reparent_thread()。