永发信息网

如何编写unix 程序防止僵尸进程的出现

答案:2  悬赏:30  手机版
解决时间 2021-03-21 17:05
  • 提问者网友:箛茗
  • 2021-03-20 16:59
如何编写unix 程序防止僵尸进程的出现
最佳答案
  • 五星知识达人网友:执傲
  • 2021-03-20 17:21
#include
#include

int main()
{
int pid = fork();
if ( pid > 0 )
{
while ( 1 )
{
sleep(3);
}
}
else if ( pid == 0 )
{
printf("i die\n");
}
}

上述程序中,fork了一个子进程,并且子进程很快就退出。父进程持续进行sleep,这样子进程就变成了僵尸进程。利用ps命令可以清晰的看到这一点。

[leconte@localhost ~]$ps axu |greptest
leconte 32600 0.0 0.0 1516 268 pts/1 S+ 20:43 0:00 ./test
leconte 32601 0.0 0.0 0 0 pts/1 Z+ 20:43 0:00 [test]
leconte 32603 0.0 0.1 5024 668 pts/2 R+ 20:43 0:00 grep test

Z+代表进程32601是僵尸进程。
僵尸进程和孤儿进程的区别是,孤儿进程是子进程还在运行,而父进程挂了,子进程被init进程收养。僵尸进程是父进程还在运行但是子进程挂了,但是父进程却没有使用wait来清理子进程的进程信息,导致子进程虽然运行实体已经消失,但是仍然在内核的进程表中占据一条记录,这样长期下去对于系统资源是一个浪费。
这时候杀掉父进程即可清理该僵尸进程。当然这并非长久之计,根本的办法是从代码上进行控制,防止类似的事情再发生。常见的方法无非是处理父进程的SIGCHLD信号,在信号处理函数里用wait或者waitpid等函数进行处理。更改后的代码如下:

#include
#include
#include

void* handler(int sig)
{
int status;

if (waitpid(-1, &status, WNOHANG) >= 0)
{
printf("child is die,i know\n");
}
}

int main()
{
signal(SIGCHLD,handler);
int pid = fork();
if ( pid > 0 )
{
while ( 1 )
{
sleep(3);
}
}
else if ( pid == 0 )
{
printf("i die\n");
}
}

这样更改后执行的输出如下:

[leconte@localhost test]$ ./test
i die
child is die,i know

可见父进程已经成功地处理了子进程的退出信号,子进程彻彻底底的消失了。

------------------------分割线----------------------

unistd.h 是 C 和 C++ 程序设计语言中提供对 POSXI 操作系统API的访问功能的头文件的名称。该头文件由 POSIX.1 标准(单一UNIX规范的基础)提出,故所有遵循该标准的操作系统和编译器均应提供该头文件(如 Unix 的所有官方版本,包括 Mac OS X、Linux等)。
对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装(英语:wrapper functions),如 fork、pipe 以及各种 I/O原语(read、write、close 等等)。
类似于 Cygwin 和 MinGW 的 Unix 兼容层也提供相应版本的 unistd.h。
全部回答
  • 1楼网友:拜訪者
  • 2021-03-20 17:37
子进程结束后,如果它的结束状态没有被父进程用wait,waitpid等系统调用来获取了话,此时这个子进程就叫zombie process.

下面的程序就演示了如何通过wait调用来获取子进程退出状态。在用户第一次回车之前,通过ps命令,应该可以看到子进程是 defunct 状态 (也就是zombie态),而一旦按下回车,wait被调用,此时通过ps命令就无法看到那个zombie了。所以防止zombie process的方法就是通过wait/waitpid等调用来解决。对这个程序有什么问题,可以baidu hi我。

#include
#include
#include

int main()
{
int pid;

pid = fork();

if (pid == 0)
{

printf("This is child process,pid=%d,bye!\n", getpid());
exit(0);
}

sleep(1);
printf("Press return to remove zombie process\n");
getchar();


wait(NULL);

printf("Press return to exit\n");
getchar();
return 0;
}
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯