程序运行期间通过ps命令的确没有发现僵尸进程的存在 。
在man文档中有这段话:
Note that even though the default disposition of SIGCHLD is "ignore", explicitly setting the disposition to SIG_IGN results in different treatment of zombie process children.
意思是说尽管系统对信号SIGCHLD的默认处理就是“ignore”,但是显示的设置成SIG_IGN的处理方式在在这里会表现不同的处理方式(即子进程结束后,资源由系统自动收回,所以不会产生僵尸进程),这是信号SIGCHLD与其他信号的不同之处 。
在man文档中同样有这样一段话:
The original POSIX standard left the behavior of setting SIGCHLD to SIG_IGN unspecified. 看来这个方法不是每个平台都使用,尤其在一些老的系统中,兼容性不是很好,所以如果你在写一个可移植的程序的话,不推荐使用这个方法 。
第二种方法,即通过两次fork来避免僵尸进程,我们来看一个例子avoid_zombie2.c:
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <errno.h> int main(int argc, const char *argv[]) { pid_t pid; while (1) { if ((pid = fork()) == 0) { /* child */ if ((pid = fork()) > 0) _exit(0); sleep(1); printf("grandchild, parent id = %ldn", (long)getppid()); _exit(0); } if (waitpid(-1, NULL, 0) != pid) { perror("waitpid error"); _exit(EXIT_FAILURE); } } exit(EXIT_SUCCESS); } 这的确是个有效的办法,但是我想这个方法不适宜网络并发服务器中,应为fork的效率是不高的 。
最后来看第三种方法,也是最通用的方法
先看我们的测试程序avoid_zombie3.c
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <libgen.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> void avoid_zombies_handler(int signo) { pid_t pid; int exit_status; int saved_errno = errno; while ((pid = waitpid(-1, &exit_status, WNOHANG)) > 0) { /* do nothing */ } errno = saved_errno; } int main(int argc, char *argv[]) { pid_t pid; int status; struct sigaction child_act; memset(&child_act, 0, sizeof(struct sigaction)); child_act.sa_handler = avoid_zombies_handler; child_act.sa_flags = SA_RESTART | SA_NOCLDSTOP; sigemptyset(&child_act.sa_mask); if (sigaction(SIGCHLD, &child_act, NULL) == -1) { perror("sigaction error"); _exit(EXIT_FAILURE); } while (1) { if ((pid = fork()) == 0) { /* child process */ _exit(0); } else if (pid > 0) { /* parent process */ } } _exit(EXIT_SUCCESS); }
推荐阅读
- 10个很棒的JavaScript库,提升Web开发效率
- 科技之手点点,有机茶产业技术升级开发示范项目通过验收
- 用 testdisk 恢复 Linux 上已删除的文件
- 记一次使用next.js开发官网经历
- 使用 GNU bc 在 Linux Shell 中进行数学运算
- springcloud微服务架构开发实战:分布式消息总线
- 开发古茶山旅游,通关古茶山
- 谈谈如何学习Linux
- 如何获取Linux或者macOS系统版本相关信息
- 小程序云开发支持公众号网页开发了
