fork()函数和僵尸进程和孤儿进程
Linux 下通过fork()函数来产生新的进程,新的进程和原来的进程的各种数据和代码几乎是一模一样的,但是创建了新的进程之后,这个两个的进程就是异步的,指不定是谁先结束,这个时候就有可能父进程先结束,子进程没有结束,也有可能子进程先结束,然后父进程在结束。这个就会有孤儿进程和僵尸进程的问题。
孤儿进程,就是没有父进程被杀死了,没有了父进程,然后统一的被孤儿院进程init收养。所以一般没有什么危害。
僵尸进程就是子进程退出了之后没有父进程没有调用wait()或者是waitpid()进行资源回收。没有人管了,但是子进程的进程描述符还在系统里面,所以叫做僵尸进程,通过ps指令可以看到状态为z的。
说句不礼貌的话,孤儿进程就是“父亲死了,没有人管 。僵尸进程是”死了没有人收尸”。仅仅是为了记忆。没有别的意思。
首先,每个进程在运行的时候回有各自的pid 这个pid 是 是表示该进程的唯一的ID 号的。 可以通过getpid() 函数获得,通过getppid()获得其父进程的pid。
进程创建
当我们用fork()函数进程创建子进程的时候,通常是这么写的
void main() { //前面一大堆程序 pid_t pid; pid=fork(); if(pid ==0) { //子进程处理的内容 }else { //父进程处理的内容 } }
父进程和子进程的代码一模一样,但是不会执行fork()函数,不然就子进程再创建子进程,没完没了了。子进程不会执行fork(),所以会直接 返回0 ,然后从fork()后面继续执行。所以,子进程里面 pid=0。但是父进程里面会返回子进程的pid。所以会不一样,我们一般通过一个if语句进行判断一下。因为这里的部分子进程和父进程都会执行了。这个就是一般的子进程的创建
孤儿进程和僵尸进程
父进程添加一个对SIGCHILD信号的处理函数,比如sig_child(),然后在这个函数里面调用wait()对子进程进程处理。
signal(SIGCHLD,sig_child);
或者是fork()两次,在子进程里面继续fork()产生“孙子进程”然后把子进程沙雕,用wait()回收,让孙子进程处于孤儿状态,那么他们退出后,就会有系统init进行回收了。