2021-10-24

3.进程管理

3.1 进程:处于执行期程序和相关资源的总称

线程:私有:进程栈,程序计数器,进程寄存器
进程资源:打开的文件,挂起的信号,内核内部数据,处理器状态,内存地址空间,数据段
调用fork()来创建子进程
exee()创建地址空间
exit()退出进程
父进程调用wait4()查看子进程是否终结
陷入等待时,进程退出执行后被设置为僵死,直到父进程调用wait(),waitpid()

进程描述符及任务结构

进程描述符task_struct结构体里的成员变量被用来描述进程信息,slab分配器用来分配task_struct,thread_info结构体内部有一个指向进程描述符的指针,它被存放在进程内核栈的底部,PID号唯一的标识了某个进程,PID最大值实际上是内核中允许同时存在进程的总数,最大值越小,转一圈就越快,且数值大的进程迟运行。
current宏负责查找当前进程的描述符

进程状态

1.TASK_RUNNING 运行:进程是可执行的
2.TASK_INTERRUOTIBLE可中断的:等待状态
3.TASK_UNINTERRUOTIBLE不可中断:等待状态,并不会被信号唤醒
4.TASK_TRACED被其他进程跟踪的进程
5.TASK_STOPPED停止执行

3.2.6 进程家族树

所有进程都是一个PID为1的init进程的后代,这个进程在内核启动最后被调用,用于初始化并启动相关进程,此进程的描述符init_task是静态分配的
遍历可执行双向链表可以遍历系统中所有进程

写时拷贝

在创建子进程时,如果子进程不需要写入,就不必拷贝一份父进程资源
fork():1.创建内核栈,描述符和描述符指针
2.检查子进程数量是否超过限制
3.把拷贝来的描述符里的某些值初始化
4.设置为不可中断态
5.设置进程PID
6.根据传递给clone()的参数(资源权限描述),进行各种资源分配
vfork():不拷贝父进程页表项,只能读

3.4 进程在linux中的实现

linux内核把线程当作进程对待,线程没有什么私有资源的特别描述,只有共有资源的描述
clone()可加参数来设定创建子进程的需共享资源

内核线程

在内核后台运行,跟用户空间没有交集,也没有被分配进程空间

3.5 进程终结

终结时释放所有资源,并把其告诉父进程:记账信息,文件描述符,文件系统的引用计数,切换到新进程。。。
如果子进程正在执行时父进程退出了,它就会僵死在那里永远不会被释放,变成孤儿;为了防止,要给它和它的兄弟们找养父进程,如果它所在的线程组没有其他进程,就把它交给init进程;找到它的兄弟,只需遍历子进程链表;
init会调用wait()清除所有的僵死进程;