[经验] 2440学习(九)进程的创建

lonerzf   2014-7-28 15:52 楼主



参考文献:  
blog.csdn.net/zhandoushi1982/article/details/5361924
blog.csdn.net/mybelief321/article/details/9054405
blog.csdn.net/fengwei321123/article/details/9301409


一、任务、进程、线程三者关系


   任务: 任务是一个逻辑概念,指由一个软件完成的任务,或者是一系列共同达到某一目的的操作。
   进程: 进程是指一个具有独立功能的程序在某个数据集上的一次动态执行过程,它是系统进行资源分配和调度的最小单元
   线程: 线程是进程内独立的一条运行路线,是处理器调度的最小单元,也可以成为轻量级进程。
   ①通常一个任务是一个程序的一次执行,一个任务包含一个或多个完成独立功能的子任务,这个独立的子任务就是进程或线程。
   ②一个进程可以拥有多个线程,每个线程必须有一个父进程。


    在Linux中,创建一个新进程的唯一方法是使用fork()函数。


fork() 函数的语法如下:
0.png


先看下面程序:
1.png


运行结果如下:
2.png


为什么会出现这个情况呢?
原因在于fork之后,操作系统会复制一个与父进程完全相同的子进程,虽说是父子关系,但是在操作系统看来,他们更像兄弟关系,这2个进程共享代码空间,但是数据空间是互相独立的,子进程数据空间中的内容是父进程的完整拷贝,指令指针也完全相同。只有一点不同,如果fork成功,子进程中fork的返回值是0,父进程中fork的返回值是子进程的进程号;如果fork不成功,父进程会返回错误。可以这样想象,2个进程一直同时运行,而且步调一致,在fork之后,他们分别作不同的工作,也就是分岔了。这也是fork为什么叫fork的原因。
      
注意
fork()后子父进程的得到的返回值是子进程的进程号,父进程只有执行getpid()之后才得到它自己的进程号。



二、fork与vfork的区别
1. fork要拷贝父进程的数据段;而vfork则不需要完全拷贝父进程的数据段,在子进程没有调用exec和exit之前,子进程与父进程共享数据段
2. fork不对父子进程的执行次序进行任何限制;而在vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit之后,父子进程的执行次序才不再有限制。


三、僵尸进程是如何产生的

给进程设置僵尸状态的目的是维护子进程的信息,以便父进程在以后某个时间获取。这些信息包括子进程的进程ID、终止状态以及资源利用信息(CPU时间,内存使用量等等)。如果一个进程终止,而该进程有子进程处于僵尸状态,那么它的所有僵尸子进程的父进程ID将被重置为1(init进程)。继承这些子进程的init进程将清理它们(init进程将wait它们,从而去除僵尸状态)。
如果子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用 waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程,无法正常结束,此时即使是root身份kill-9也不能杀死僵尸进程。


下面代码段因子进程会先于父进程退出,会产生僵尸进程。
3.png

通过ps auwx 可以看到5088 5093进程中的5093(子进程)的状态是Z,即僵尸进程。
4.png

如何避免呢,下一节继续。
这孩子,成熟的象征,理智的典范。

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复