linux下的进程管理

linux内核设计与实现学习笔记

进程管理

进程

Fork()

父进程                          子进程

Exec() 载入程序

Exit():进程退出执行,处于僵死状态

负责进程内存销毁(task_struct保留)

Wait4()::子进程退出执行或子进程在

Ptrace下中断而出发wait4

负责查看子进程的task_struct

销毁它,销毁后子进程彻底消失


进程创建过程

Fork(),vfork(),__clone() -> clone() -> do_fork() -> copy_process() ->dup_task_struce()

1.Dup_task_struct() 为新进程创建一个内核线程,thread_info,task_struct,新建的结构值和父进程完全一样。

2.检查新进程创建后,用户拥有的进程数是否超出给他分配的资源限制

3.进程描述符的大多成员被赋值为初始值(这是父进程与子进程区别开来),进程描述符的大多数数据都是共享的(比如进程打开的文件描述符)

4.子进程的状态被设置为TASK_UNINTERRUPTIBLE

5.copy_process()调用copy_flags()设置进程的一些标志位

6.调用get_pid()为进程获取一个PID

7.根据传递给clone()的参数标志,copy_process()拷贝或共享打开的文件,文件系统信息,信号处理函数,进程地址空间和命名空间等


进程的退出do_exit()

1、task_struce中的标志成员设置为PF_EXITING

2、调用del_timer_syne()删除任一内核定时器(挂起)

3、调用_exit_mm()放弃进程占用的mm_struct,(mm_struct的共享计数-1,如果为0则彻底释放他)

4、调用exit_sem()退出进程通信,如果进程排队等候IPC,它离开队列

5、调用_exit_files()递减文件描述符

6、调用_exit_fs()文件系统数据

7、调用exit_namespace()进程名字空间

8、调用exit_sighand()信号处理函数的引用计数

9、task_struct中的exit_code码标示为exit()提供的参数

10、调用exit_notify()向父进程发出信号,将本身的状态设置为TASK_ZOMBIE

11、调用schedule()切换到其他进程

注:处于ZOMBIE状态的进程不会再被调用,他占用的资源仅为内核站、thread_info,task_struct.


进程描述符的终结

父进程调用wiat(),他的基本动作是挂起调用他的进程,直到其中的一个子进程退出,此时函数会返回该子进程的PID

wait4会调用release_task()调用一下函数完成进程描述符的释放工作:

1、调用free_uid来减少进程拥有者的进程计数

2、调用unhash_process()pidhash上删除该进程,同时也要从task_list中删除该进程

3、如果进程正在被ptrace跟踪,release_task()将跟踪的附近横重设为其最初的父进程并将其在ptrace_list中删除

4、调用put_task_struct()释放进程内核栈和thread_info结构所占用的页,释放task_struct所占用的slab高速缓存


程序的执行:将可执行文件载入到进程的地址空间执行,一帮的命令是在用户空间执行,在程序调用了系统调用或触发了异常则会陷入内核空间。


Linux下进程和线程的区别:

Linux没有具体划分进程和线程,处理器执行的基本单位是进程,而所谓的“进程的多个线程”是指共享地址空间但是有独自的进程描述符的进程组



你可能感兴趣的:(linux下的进程管理)