Linux2.6进程的创建与删除

一、进程的创建

1.系统调用clone()与fork()的区别:

 资源的继承方式参数区分父进程与子进程的方法
fork()全部复制,即父进程的所有资源全部通过数据结构的复制传给子进程无参数父进程与子进程,从fork()返回时的返回值不同,以此区分二者。子进程返回0.父进程返回子进程的pid
clone()有选择地将资源复制给子进程,没有复制的资源通过指针复制的方式与子进程共享(共享与复制的关系见2)有参数,用于设置资源复制的方式clone()所产生的子线程的PID有可能是0,因此采用比较系统堆栈指针的方法来区分二者。
note:

(1)为什么返回值的方式对fork()适用?

因为fork()后子进程拥有独立的资源,是一个进程,有自己的独一无二的PID,不可能是0

(2)为什么返回的方式对clone()不适用?

因为clone()不一定复制资源,产生的有可能是一个线程。线程的PID与它所在的线程组的PID相同。如果父线程的PID是0,那么子线程的PID也是0。父与子的返回值是一样的,无法区分。

(3)为什么比较系统堆栈指针的方式对fork()不适用?

因为普通的进程都在用户空间,系统堆栈不知道在哪里

(4)为什么比较系统堆栈指针的方式对clone()适用?

每一个内核线程都有自己的系统空间堆栈,子线程的堆栈空间的指针必须与父线程不同

(5)它们最终都是调用do_fork()创建子进程的

note中的内容讲得不好理解,因为有几句话强调线程与进程的区别,有几句话里进程指的是进程或线程,如果结合Linux2.6进程-1中的表格,会有助于对note的理解


2.线程创建函数kernel_thread(),本质也是调用do_fork(),但是不复制进程的页表。因为新内核线程不会访问用户态地址空间


3.共享与复制的关系

(1)相同点:

复制完全之初,子进程有了一个副本,它的内容与父进程的正本内容基本相同。

(2)不同点-共享:

共享是指仅复制指针,是浅层复制。事实上,父与子都是对同一地址进程操作。

父与子并发地对同一堆栈区进行操作,这种行为是致命的。

通常的解决方法是:扣留父进程,只让子进程返回。当子进程有了自己的用户空间,或子进程确定不再使用父的用户空间(死亡)后,才能让父返回。

(3)不同点-复制:

互不干扰


4.所有用于创建子进程的系统调用,最终都是通过调用do_fork()创建子进程的

(1)获取一个空进程项

(2)获取一页内存

(3)自制当前进程的数据结构到内存中

(4)新进程设置为不可中断等待

(5)对新进程的数据结构修改

note:不分配物理内存,写时复制


5.写时复制

(1)将父进程的页面表项改为写保护

(2)把表项设置到子进程的页面表中

(3)当父进程或子进程企图写页面时,发生页面异常,给要写的进程另分配一个物理页面,此时才是真正的复制

(5)置两个页面都为可写


6.父进程创建子进程后,父进程剩余节拍数被划分为两等份,一份给父,一份给子。

一个进程不能通过创建多个后代来霸占资源


二、进程的撤消与删除

1.子进程被终止以后,不能立即删除,因为它可能还有父进程需要的信息。

只有父进程发出了与被终止进程相关的wait类系统调用后,才允许由父进程为子进程彻底删除


2.子进程在do_exit()的最后,会调用schedule()。这个函数的返回条件是再次被调度。但此进程再也不会被调度,因此schedule()不会返回,do_exit()也不会被返回

此时进程的状态是ZOMBIE,即调度被无限推迟,直到父进程收到信号后来处理后事,将其task_struct释放,这个进程就彻底消失了。


3.父进程要为子进程处理后事。

如果一个进程被终止前还有子进程,则要把子进程托付给某个进程。

如果父进程是一个线程组的成员,就把子进程托付给线程组的下一个成员。

否则就把子进程托付给0号进程


4.中断服务程序、软件中断服务程序、0号进程、1号进程不允许终止。

转载于:https://www.cnblogs.com/windmissing/archive/2012/05/22/2559813.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值