感觉僵尸进程和守护进程有点类似
错误想法:僵尸进程和守护进程都是父进程退出,但是子进程不退出
解析:作为僵尸进程的子进程是已经退出了的,但是作为守护进程的子进程是未退出的
(僵尸进程的产生是因为子进程已经退出,但是它的父进程还没有来得及调用wait()或waitpid()等函数来获取它的终止状态,因此子进程的进程描述符仍然存在于系统中,但是已经没有可以处理它的父进程了。这样子进程就成为了僵尸进程。)
详细解析:
僵尸进程:父进程先退出,子进程后退出,父进程没有来得及调用wait或waitpid来获取其终止状态.
守护进程:父进程退出,但是子进程没有退出(这个子进程就是未来的守护进程),
子进程调用setsid来创建新的会话,脱离掉原来的控制终端,从而成为一个独立的守护进程.
(守护进程通常不会退出,除非产生了严重的错误或系统关闭)
守护进程如何实现: (1)创建子进程,终止父进程。方法是调用fork() 产生一个子进程,然后使父进程退出。 (2)调用setsid() 创建一个新会话。 (3)将当前目录更改为根目录chdir。使用fork() 创建的子进程也继承了父进程的当前工作目录。 (4)重设文件权限掩码umask。文件权限掩码是指屏蔽掉文件权限中的对应位。 (5)关闭不再需要的文件描述符close。子进程从父进程继承打开的文件描述符。
eg: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #include <sys/stat.h> #define MAXFILE 65535 int main(){ //第一步:创建进程 int pid = fork(); if (pid > 0) { exit(0);//结束父进程 } else if (pid < 0){ printf("fork error!\n"); exit(1);//fork失败,退出 } //第二步:子进程成为新的会话组长和进程组长,并与控制终端分离 setsid(); //第三步:改变工作目录到 chdir("/"); //第四步:重设文件创建掩模 umask(0); //第五步:关闭打开的文件描述符 for (int i=0; i<MAXFILE; ++i) { close(i); sleep(2); } return 0; }