这几天上操作系统原理上的比较晕,今晚继续看Linux编程顺便看懂了好几个问题。

    随便写几句。

    首先进程和程序的区别,特南鲍姆那本操作系统书上有个很形象的例子,程序相当于食谱做菜步骤,而进程相当于做饭的过程。也就是说进程是一个过程,是用来执行程序代码的。这就有一个问题,如果一个进程在执行一段代码,我想办法把代码给换了会怎么样,于是就有了exec函数,这个函数可以把一个进程所执行的程序代码换掉,执行这个函数后进程还是那个进程,PID什么的没变,但代码不再是以前的代码了,将继续执行新的代码。

与此相关的fork函数,会创建另一个新进程并把当前进程相关的环境变量、堆栈等复制一份给那个新进程(我们将之称为子进程),由于这俩进程共享一份代码,却有不同的内存地址空间(包括环境变量、堆栈等数据),这样的话,每一个进程的堆栈是一样的,当前两个进程都在fork函数中等待返回,于是会返回两次,虽然返回两次但他们执行同一份代码,父进程按照堆栈的指示返回fork值(子进程ID),子进程同样要返回fork值(0),俩进程在各自的进程内返回了自己专属的fork返回值。于是在接下来的共享代码中就可以用switch-case语句根据两次返回值的不同选择不同的代码执行。父进程和子进程里fork返回值分别为PID和0,执行这同一段代码到了switch-case处便会依据返回值选择不同的分支执行。说的略罗嗦。

    如果子进程先挂了,那么他的进程表项不会立即释放,因为之后他的父进程可能会提取一些退出信息,那么这子进程已经挂了,但没释放,就叫做僵尸进程。等到父进程挂了之后子进程的进程表项也就释放了,如果子进程成僵尸了,父进程却异常终止,那么子进程托孤给init进程,由他来释放。

    如果父进程先挂了,那么子进程执行完任务并挂了之后,进程表项就立刻被释放了。