免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3044 | 回复: 10
打印 上一主题 下一主题

请教避免僵死进程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-09 18:44 |只看该作者 |倒序浏览
apue中提到调用fork两次以避免僵死进程,代码是这样的

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
    pid_t   pid;

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {     /* first child */
        if ((pid = fork()) < 0)
            err_sys("fork error");
        else if (pid > 0)
            exit(0);    /* parent from second fork == first child */
        /*
         * We're the second child; our parent becomes init as soon
         * as our real parent calls exit() in the statement above.
         * Here's where we'd continue executing, knowing that when
         * we're done, init will reap our status.
         */
        sleep(2);
        printf("second child, parent pid = %d\n", getppid());
        exit(0);
    }
   
    if (waitpid(pid, NULL, 0) != pid)  /* wait for first child */
        err_sys("waitpid error");

    /*
     * We're the parent (the original process); we continue executing,
     * knowing that we're not the parent of the second child.
     */
    exit(0);
}


我不清楚为什么要强调调用两次fork,因为如果把代码改成如下这样,也可以避免产生僵死进程

int
main(void)
{
    pid_t   pid;

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {     /* first child */

        sleep(2);
        printf("second child, parent pid = %d\n", getppid());
        exit(0);
    }

    exit(0);
}

父进程调用一次fork后,直接调用exit结束,那么子进程同样会被init进程接收
同样不会产生僵死进程,
为什么必须调用两次呢,是有什么深意吗
请指教

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2012-02-09 19:51 |只看该作者
假设一个服务器程序,你是不是每次都要fork一个子进程然后自己退掉呢?

一个服务器程序可以fork fork很多的子进程并防止僵死进程出现

论坛徽章:
0
3 [报告]
发表于 2012-02-09 20:22 |只看该作者
回复 2# lxyscls


    有道理,谢谢,fork两次是从实用性的角度出发,并非从技术角度考虑

论坛徽章:
0
4 [报告]
发表于 2012-02-10 11:51 |只看该作者
本身僵尸进程产生的原因是父进程没有处理子进程退出时的信号量,同时父子进程各有各的工作处理。 apue通过两次fork造成了父进程进行父进程的事儿,不用wait。子进程干子进程的事儿,二次fork父进程变成init进程,init接管子进程的退出信息,销毁进程数据块从而没有僵尸进程。
至于楼主写的代码跟以下代码类似把。只不过lz调用了一次无效的fork,子进程的父进程变成了init。 以下的进程的父进程是shell,也不会造成僵尸。哈。
int
main(void)
{
        printf("second child, parent pid = %d\n", getppid());
        exit(0);

}

论坛徽章:
0
5 [报告]
发表于 2012-02-10 12:52 |只看该作者
fork一次就能解决僵尸进程,fork二次是解决进程组、会话组之类的问题的

论坛徽章:
0
6 [报告]
发表于 2012-02-11 16:49 |只看该作者
fork两次是为了不让child再当session leader。

论坛徽章:
0
7 [报告]
发表于 2012-02-16 17:10 |只看该作者
这个我在书上看到过,一直就没有理解的清楚些,请您讲的透彻些,我再对照书仔细理解一下回复 6# 鸡丝拌面


   

论坛徽章:
0
8 [报告]
发表于 2012-02-20 16:37 |只看该作者
tianhailong 发表于 2012-02-16 17:10
这个我在书上看到过,一直就没有理解的清楚些,请您讲的透彻些,我再对照书仔细理解一下回复 6# 鸡丝拌面
...



If the daemon never opens any terminal devices thereafter, then we don’t need to worry about the daemon reacquiring a controlling terminal. If the daemon might later open a terminal device, then we must take steps to ensure that the device does not become the controlling terminal. We can do this in two ways:

– Specify the O_NOCTTY flag on any open() that may apply to a terminal device.

– Alternatively, and more simply, perform a second fork() after the setsid() call, and again have the parent exit and the (grand)child continue. This ensures that the child is not the session leader, and thus, according to the System V conventions for the acquisition of a controlling terminal (which Linux follows), the process can never reacquire a controlling terminal.


这段写得很明确了。

论坛徽章:
0
9 [报告]
发表于 2012-02-21 11:57 |只看该作者
wait一下!

“谁打开谁关闭,谁申请谁释放”

你创建的子进程,你就有责任为其收尸

论坛徽章:
3
巳蛇
日期:2013-10-03 10:41:48申猴
日期:2014-07-29 16:12:04天蝎座
日期:2014-08-21 09:24:52
10 [报告]
发表于 2012-02-21 17:25 |只看该作者
父进程不调用wait,当子进程退出的时候就会产生僵尸进程.
如果父进程fork之后直接就退出了,那也不会有僵尸进程
两次fork一般是因为服务器的父进程要一直都在的,他需要fork来出来客户端的请求,这个时候父进程就需要wait或者两次fork
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP