Linux编程之调用fork()两次以避免僵死进程

当我们只fork()一次后,存在父进程和子进程。这时有两种方法来避免产生僵尸进程:

父进程调用waitpid()等函数来接收子进程退出状态。

父进程先结束,子进程则自动托管到Init进程(pid = 1)。

目前先考虑子进程先于父进程结束的情况:    

若父进程未处理子进程退出状态,在父进程退出前,子进程一直处于僵尸进程状态。

若父进程调用waitpid()(这里使用阻塞调用确保子进程先于父进程结束)来等待子进程结束,将会使父进程在调用waitpid()后进入睡眠状态,只有子进程结束父进程的waitpid()才会返回。 如果存在子进程结束,但父进程还未执行到waitpid()的情况,那么这段时期子进程也将处于僵尸进程状态。

由此,可以看出父进程与子进程有父子关系,除非保证父进程先于子进程结束或者保证父进程在子进程结束前执行waitpid(),子进程均有机会成为僵尸进程。那么如何使父进程更方便地创建不会成为僵尸进程的子进程呢?这就要用两次fork()了。

父进程一次fork()后产生一个子进程随后立即执行waitpid(子进程pid, NULL, 0)来等待子进程结束,然后子进程fork()后产生孙子进程随后立即exit(0)。这样子进程顺利终止(父进程仅仅给子进程收尸,并不需要子进程的返回值),然后父进程继续执行。这时的孙子进程由于失去了它的父进程(即是父进程的子进程),将被转交给Init进程托管。于是父进程与孙子进程无继承关系了,它们的父进程均为Init,Init进程在其子进程结束时会自动收尸,这样也就不会产生僵尸进程了。

#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>    

int main(void)
{
   pid_t pid;       

    if ((pid = fork()) < 0)
    {
        fprintf(stderr,"Fork error!/n");
        exit(-1);
    }
    else if (pid == 0) /* first child */
    {
        if ((pid = fork()) < 0)
        {
            fprintf(stderr,"Fork error!/n");
            exit(-1);
        }
        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 */
    {
        fprintf(stderr,"Waitpid error!/n");
        exit(-1);
    }       

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索进程
, 结束进程
, fork
, exit
, fork()
, pid
, 多进程
, 子进程
, 执行两次
, monitoringhost进程
, 进程winformc#
, 编程控制pid
, waitpid
parent
守护进程 fork两次、僵死进程、linux查看僵死进程、linux僵死进程、oracle僵死进程是什么,以便于您获取更多的相关知识。

时间: 2024-12-21 22:01:51

Linux编程之调用fork()两次以避免僵死进程的相关文章

c++-C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗?

问题描述 C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? 解决方案 C和C++最大的区别当然是C++支持OOP,但是它们也有一些细节上的不同.比如C++支持模板.引用.命名空间等,C++ 11/14更是增加了Lambda表达式.类型推断.自动指针等等. 解决方案二: 不是的呀,c++库是跨平台的 解决方案三: C调用C++接口c++中调用c接口的问题Li

Linux系统中C语言编程创建函数fork()执行解析_C 语言

最近在看进程间的通信,看到了fork()函数,虽然以前用过,这次经过思考加深了理解.现总结如下: 1.函数本身 (1)头文件 #include<unistd.h> #include<sys/types.h> (2)函数原型 pid_t fork( void); (pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中) 返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID:否则,出错返回-1 (3)函数说明 一

《Linux系统编程(第2版)》——1.4 Linux编程的概念

1.4 Linux编程的概念 本节给出了Linux系统提供的服务的简要概述.所有的UNIX系统,包括Linux,提供了共同的抽象和接口集合.实际上,UNIX本身就是由这些共性定义的,比如对文件和进程的抽象.管道和socket的管理接口等等,都构成了UNIX系统的核心. 本概述假定你对Linux环境很熟悉:会使用shell的基础命令.能够编译简单的C程序.它不是关于Linux或其编程环境的,而是关于Linux系统编程的基础. 1.4.1 文件和文件系统文件是Linux系统中最基础最重要的抽象.Li

Linux 编程中的API函数和系统调用的关系【转】

转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号   API:(Application Programming Interface,应用程序编程接口)  指的是我们用户程序编程调用的如read(),write(),malloc(),free()之类的调用的是glibc库提供的库函数.API直接提供给用户编程使用,运行在用户态.  我们经常说到的POSIX(

[综合面试] 牛人整理分享的面试知识:操作系统、计算机网络、设计模式、Linux编程,数据结构总结

感谢IT面试群 S-北京-陈磊 的整理分享. 基础篇:操作系统.计算机网络.设计模式 一:操作系统 1. 进程的有哪几种状态,状态转换图,及导致转换的事件. 2. 进程与线程的区别. 3. 进程通信的几种方式. 4. 线程同步几种方式.(一定要会写生产者.消费者问题,完全消化理解) 5. 线程的实现方式. (也就是用户线程与内核线程的区别) 6. 用户态和核心态的区别. 7. 用户栈和内核栈的区别. 8. 内存池.进程池.线程池.(c++程序员必须掌握) 9. 死锁的概念,导致死锁的原因. 10

Linux下C调用C++接口详解

    C++做久了,经常用C++的方式去思考问题,有时候就突然发现自己不太会写C程序了.写程序的时候,难免会用到第三方插件或者是库,而这些插件或者库很多时候都不能完全满足我们的需求,遇到这种情况,如果全是C++,那好办,写个适配器就OK了,关于适配器模式参考我的博客<C++ Adaptor 设计模式>    如果要提供给C程序使用,那就需要自己封装C程序可以使用的库.前几天在CSDN Linux/Unix版闲逛的时候,遇到一位网友,他问这样的问题:(原话我记不住了,大致是这个意思)我要要封装

点评五款用于 Linux 编程的内存调试器

点评五款用于 Linux 编程的内存调试器 Credit: Moini 作为一个程序员,我知道我肯定会犯错误--怎么可能不犯错!程序员也是人啊.有的错误能在编码过程中及时发现,而有些却得等到软件测试了才能显露出来.然而,还有一类错误并不能在这两个阶段被解决,这就导致软件不能正常运行,甚至是提前终止. 如果你还没猜出是那种错误,我说的就是和内存相关的错误.手动调试这些错误不仅耗时,而且很难发现并纠正.值得一提的是,这种错误很常见,特别是在用 C/C++ 这类允许手动管理内存的语言编写的软件里. 幸

linux编程获取本机网络相关参数

getifaddrs()和struct ifaddrs的使用,获取本机IP 博客分类:    Linux C编程       ifaddrs结构体定义如下: C代码   struct ifaddrs    {        struct ifaddrs  *ifa_next;    /* Next item in list */        char            *ifa_name;    /* Name of interface */        unsigned int    

linux编程-关于Linux的三个编程题,想了半天毫无头绪,感觉Linux编程好复杂。求大家帮助帮助我,谢谢。

问题描述 关于Linux的三个编程题,想了半天毫无头绪,感觉Linux编程好复杂.求大家帮助帮助我,谢谢. 1:子进程每隔一秒向文件写入信息,父进程每隔三秒读出子进程所写的信息并输出到屏幕. 2:模拟shell,设计一个交互式命令处理程序,注意对命令参数和环境参数的处理. 3:编写一个守护进程,实现功能为:每隔一秒,向当前目录下的hello文件里写入一行helloworld. 解决方案 Linux设备驱动编程之复杂设备驱动25岁了,是学linux运维还是编程好呢?求指点下 .. 解决方案二: 楼