怎样 detach 子进程
通过 fork 创建进程后,父进程可以使用 waitpid 来获取子进程的结束状态。
如果子进程先于父进程退出,而父进程没有调用 waitpid 的话,子进程将一直存续下去以保持结束状态可以被获取。
此时,子进程被称为僵尸进程。
如果子进程没有被调用 waitpid 而父进程退出了,此时子进程被称为孤儿进程,它会被 init进程(PID为1) 领养并调用waitpid回收。
有时我们并不关心子进程的结束状态,希望像 pthread_detach 一样示释放子进程。有以下两种方法可以实现:
- 父进程调用 fork创建子进程A并对其调用waitpid,子进程A再次fork创建子进程B并退出。
这样一来,子进程A 由父进程回收,子进程B 成为孤儿进程被init进程回收。
- 父进程调用 signal(SIGCHLD, SIG_IGN)
SIGCHLD是子进程状态发生变化时产生的信号,默认就是忽略的,但是必须显示调用才会释放子进程。
守护进程
上述方法一中创建孤儿进程的方法常被用于创建守护进程。常用步骤如下:
- 调用 fork创建子进程,然后父进程退出。
- 子调用 setsid创建新的会话和进程组,从而避免被原先的会话、进程组以及会话终端影响。
- 调用 chdir设置工作目录。
- 调用 umask设置文件掩码(通常设为umask(0))。
- 关闭不需要的资源(从父进程继承的文件描述符等)。
除第一步外的后续步骤并不是必须的,但大部分情况下是必要的。