Linux内核设计与实现读书笔记——第三章 进程管理
20135111李光豫
3.1进程
1.进程即处于执行期的程序,并不局限于一个可执行的代码,是处于执行期程序以及其相关资源的总称。
2.Linux系统中,对于进程和线程并没有明显的区分,线程是一种特殊的进程。
3.Linux系统中,常用fork()进程创建子进程。调用fork()进程的成之为其子进程的父进程。
4.fork()继承实际上由clone()系统调用实现。最后通过exit()退出执行。
3.2任务描述符及任务结构
1.任务队列实质上是进程的列表,是一种双向循环链表,其中每一项的类型均为task_struct.
2.Linux通过slab分配器分配task_struct结构,
3.进程描述符(PID),是每一个进程的唯一标识值,最大值32768.
4.PID中state描述了进程当前的状态,每个进程都必然处于下列五中状态中的一种。
TASK_RUNNING(可运行):标识该进程正在运行或等待运行,这是进程在用户空间执行的唯一可能状态。
TASK_INTERRUPTLBLE:(可中断):进程在睡眠,等待某种条件的达成,等待被唤醒。
TASK_UNINTERRUPTLBLR:(不可中断)
_TASK_TRACED:被其他进程跟踪的进程
_TASK_STOPPED:停止执行进程
5.内核一般使用set_task_state(state,task)来调整进程状态
3.3进程创建
1.Linux将进程创建拆分为两个单独函数:fork()与exec(),前者拷贝当前进程创建子进程,后者负责读取可执行文件并将其载入地址空间开始运行。
2.Linux的fork()函数具有写时拷贝功能,只有在需要时,数据才会被复制。
3.fork()
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。此时,两个进程都从fork开始往下执行,只是pid不同。
3.4线程在Linux中实现
1.线程的创建和进程创建类似,但是在调用clone()时候需要传递一些参数标志来指明需要共享的资源。
2.传递的参数决定了新创建进程的行为方式和父子进程之间的共享种类。
3.内核线程与普通线程的区别在于:内核线程没有独立的地址空间,仅在内核空间运行。内核线程只能由其他内核线程创建,其祖先为kthreadd
3.5进程终结
进程终结大部分靠do_exit()来实现,它的工作包括:删除任一内核定时器、输出记账信息、释放地址空间、为子进程重新寻找养父等等。