相关文章推荐
难过的大熊猫  ·  printf打印(u8/.../int/.. ...·  2 月前    · 
坏坏的路灯  ·  编写一个程序,返回一个按字母顺序排序的字符串 ...·  1 年前    · 
朝气蓬勃的圣诞树  ·  Android ...·  1 年前    · 
满身肌肉的滑板  ·  androidstudio ...·  1 年前    · 
博学的绿茶  ·  laravel实现一个上传图片的接口,并建立 ...·  1 年前    · 
有胆有识的玉米  ·  Seaborn ...·  3 年前    · 
Code  ›  父进程退出时如何确保子进程退出?开发者社区
fork printf
https://cloud.tencent.com/developer/article/1497217
绅士的大白菜
3 年前
作者头像
编程珠玑
0 篇文章

父进程退出时如何确保子进程退出?

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 编程珠玑 > 父进程退出时如何确保子进程退出?

父进程退出时如何确保子进程退出?

作者头像
编程珠玑
发布 于 2019-09-02 21:59:18
7.3K 0
发布 于 2019-09-02 21:59:18
举报

前言

子进程退出的时候,父进程能够收到子进程退出的信号,便于管理,但是有时候又需要在父进程退出的时候,子进程也退出,该怎么办呢?

父进程退出时,子进程会如何?

一般情况下,父进程退出后,是不会通知子进程的,这个时候子进程会成为 孤儿进程 ,最终被init进程收养。我们先来看一下这种情况。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
int main(void)
    pid_t pid;
    //fork一个进程
    pid = fork();
    //创建失败
    if (pid < 0)
        perror("fork error:");
        exit(1);
    //子进程
    if (pid == 0)
        printf("child process.\n");
        printf("child  pid:%d,parent pid:%d\n",getpid(),getppid());
        printf("sleep 10 seconds.\n");
        //sleep一段时间,让父进程先退出,为了便于观察,sleep 10s
        sleep(10);
        printf("now child pid: %d parent pid:%d\n",getpid(),getppid());
    //父进程
        printf("parent process.\n");
        sleep(1);
    return 0;
}

在这个程序中,我们为了让父进程先退出,子进程sleep了10秒。 运行结果如下:

parent process.
child process.
child  pid:17433,parent pid:17432
sleep 10 seconds.
now child pid: 17433 parent pid:1658

从结果中可以看到,一开始子进程17433的父进程id是17432,但是在10秒后,它的父进程变成了1658。1685是什么进程呢?

$ ls -al /proc/1658/exe 
/proc/1658/exe -> /sbin/upstart

由于我使用的环境是 带有图形界面的ubuntu系统 ,所以最终并不是被我们所熟知的init进程收养,而是被一个名为/sbin/upstart的进程所收养。另外还可以观察到,该进程也是其他系统进程的父进程。

如何确保父进程退出的同时,子进程也退出?

既然如此,如何确保父进程退出的同时,子进程也退出呢?或许我们可以在子进程和父进程之间建立通信管道,一旦通信异常,则认为父进程退出,子进程自己也回收资源退出。但是这样做总觉得不是很正经。有没有已有的函数帮我们做这件事呢?prctl函数可以帮助我们。第一个参数中,有一个选项,叫做PR_GET_PDEATHSIG:

       PR_SET_PDEATHSIG (since Linux 2.1.57)
              Set  the  parent  death signal of the calling process to arg2 (either a signal value in the range 1..maxsig, or 0 to clear).
              This is the signal that the calling process will get when its parent dies.  This value is cleared for the child of a fork(2)
              and (since Linux 2.4.36 / 2.6.23) when executing a set-user-ID or set-group-ID binary, or a binary that has associated capa‐
              bilities (see capabilities(7)).  This value is preserved across execve(2).

内容很多,主要意思为:设置一个信号,当父进程退出的时候,子进程将会收到该信号。

那么根据这个,我们完全可以在父进程退出时,也给子进程一个退出的信号。程序代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <signal.h>
int main(void)
    pid_t pid;
    //fork一个进程
    pid = fork();
    //创建失败
    if (pid < 0)
        perror("fork error:");
        exit(1);
    //子进程
    if (pid == 0)
        /*父进程退出时,会收到SIGKILL信号*/
        prctl(PR_SET_PDEATHSIG,SIGKILL);
        printf("child process.\n");
        printf("child  pid:%d,parent pid:%d\n",getpid(),getppid());
        printf("sleep 10 seconds.\n");
        //sleep一段时间,让父进程先退出,为了便于观察,sleep 10s
        sleep(10);
        printf("now child pid: %d parent pid:%d\n",getpid(),getppid());
    //父进程
        printf("parent process.\n");
        sleep(1);
 
推荐文章
难过的大熊猫  ·  printf打印(u8/.../int/.../float)各类型方法开发者社区
2 月前
坏坏的路灯  ·  编写一个程序,返回一个按字母顺序排序的字符串,其中包含给定字符串中不出现的所有小写字母。_编写一个程序,返回一个按字母顺序排序的字符串,其中包含给定字符串中不出现的所有-CSDN博客
1 年前
朝气蓬勃的圣诞树  ·  Android 底部导航栏(底部Tab)最佳实践 - 门罗的魔术师 - 博客园
1 年前
满身肌肉的滑板  ·  androidstudio 添加超链接_mob64ca12f55920的技术博客_51CTO博客
1 年前
博学的绿茶  ·  laravel实现一个上传图片的接口,并建立软链接,访问图片的方法-腾讯云开发者社区-腾讯云
1 年前
有胆有识的玉米  ·  Seaborn pairplot图例--如何控制位置
3 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号