简体   繁体   English

fork():子进程检查父进程是否已死的方法?

[英]fork(): way for a child process to check if parent is dead?

Background 背景

I am writing a shared library in C, dynamically linked with LD_PRELOAD , that is meant to intercept and override network calls from the application preloading it, such as socket() , connect() , recv() , send() , etc. 我在C中编写一个共享库,与LD_PRELOAD动态链接,用于拦截和覆盖来自应用程序预加载的网络调用,如socket()connect()recv()send()等。

In the init of the library I launch a thread with pthread_create() . 在库的init中,我使用pthread_create()启动一个线程。 This thread polls some kernel memory, which is mapped to user space. 该线程轮询一些内核内存,该内存映射到用户空间。

The library is meant to be generic enough to deal with - but not limited to - networking benchmark applications such as netperf , iperf , sockperf . 该库旨在通用,足以处理 - 但不限于 - 网络基准应用程序,如netperfiperfsockperf

My issue 我的问题

Everything works fine, life is sweet in most of the cases except one. 一切都很好,大多数情况下生活都很甜蜜,除了一个。 Deamonized applications. Deamonized应用程序。 For instance, if I launch netserver (the server side of the netperf benchmarking application) as a deamon, ie without the -D parameter, one of the first things the application does is call fork() . 例如,如果我将netservernetperf基准测试应用程序的服务器端)作为deamon启动,即没有-D参数,则应用程序执行的第一件事就是调用fork() On fork, the parent is closed using exit(EXIT_SUCCESS) and the child listens for connections. 在fork上,使用exit(EXIT_SUCCESS)关闭父级,并且子级侦听连接。 The fact that the parent exits kills my polling thread. 父退出的事实会导致我的轮询线程被杀死。

So what I'd like to achieve is have the child spawn a new polling thread if the parent has gone. 所以我想要实现的是让孩子在父母已经离开的情况下产生一个新的轮询线程。 I can intercept and override the fork() call but fundamentally, how can I have the child know whether the parent has gone or not? 我可以拦截并覆盖fork()调用,但从根本上说,如何让孩子知道父母是否已经离开? I can't take any assumption because the library has to be generic. 我不能采取任何假设,因为库必须是通用的。

Thanks. 谢谢。

You can poll periodically getppid() function. 您可以定期轮询getppid()函数。 As soon as it starts to return '1' (the id of init process) - your parent is dead. 一旦它开始返回'1'(init进程的id) - 你的父亲就死了。

Update 更新

excerpt from 'man pthread_create': 摘自'man pthread_create':

The new thread terminates in one of the following ways: ... 新线程以下列方式之一终止:...

  • Any of the threads in the process calls exit(3), or the main thread performs a return from main(). 进程中的任何线程都调用exit(3),或者主线程执行main()的返回。 This causes the termination of all threads in the process. 这会导致进程中所有线程的终止。

So, if your thread is created by the netserver process that calls exit - yes this thread will be terminated 所以,如果你的线程是由调用exit的netserver进程创建的 - 是的,这个线程将被终止

你可以使用ptread_atfork(3)在孩子中启动你的线程。

About a year later, I have the answer to my own question, which was "how does a child process know that its parent is dead?" 大约一年后,我得到了我自己的问题的答案,即“儿童过程如何知道其父母死了?”

Well, the child can ask what the PID of its parent is, using getppid() . 好吧,孩子可以使用getppid()询问其父级的PID是什么。 If the parent PID is 1, then it means the child process was reparented to the init process. 如果父PID为1,则表示子进程已重新分配给init进程。 Therefore, the parent has gone. 因此,父母已经走了。

For instance: 例如:

void child_fork(void)
{
    int parent_pid;
    usleep(1);
    parent_pid = (int)getppid();

    if (parent_pid == 1)
        run_my_polling_thread();
}

Note: when a process forks the parent is put to sleep. 注意:当一个进程分叉父进程进入休眠状态时。 The child process runs first, then the parent is woken up (for Copy-on-Write optimization, I won't go into details here). 子进程首先运行,然后父进程被唤醒(对于Copy-on-Write优化,我不会在这里详细介绍)。 The usleep(1) call is here to put the child immediately to sleep so that the parent has time to wake up and terminate. usleep(1)调用是让孩子立即进入睡眠状态,以便父母有时间醒来并终止。 Before the child wakes up it will be reparented to init . 在孩子醒来之前,它将被重新定义为init

Now, at lib init time I just need to call: 现在,在lib init时,我只需要调用:

__register_atfork(NULL, NULL, child_fork, NULL)

However, this solution does not cover all cases. 但是,此解决方案并未涵盖所有情况。 For instance, what if the parent has multiple children? 例如,如果父母有多个孩子怎么办? Do I really want them all to launch a polling thread? 我真的希望他们都发布一个投票线程吗?

Right now it's an acceptable solution for me, although it's not ideal. 现在它对我来说是一个可接受的解决方案,虽然它并不理想。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM