使用prctl(PR_SET_PDEATHSIG,SIGNAL)调用父线程退出,而不是父进程退出(p

2019-09-17 13:17发布

我有一个分路到一个子进程的过程。 如果父进程中存在的子进程不应该存在的。 因此,我调用::使用prctl(PR_SET_PDEATHSIG,SIGKILL)在子进程中,如果父母去世杀死它。 什么最终发生的是父线程调用了pthread_exit,并且该线程最终被杀死的子进程的催化剂。

这里是我的代码:

parent.cpp:

#include <sys/prctl.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <iostream>

void* run(void* ptr) {

    std::cout << "thread:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;
    auto pid = fork();
    if ( pid != 0 ) {
        sleep(1);
    }
    else {
        char* arg = NULL;
        execv("./child", &arg);
    }
    return NULL;
}

int main() {

    std::cout << "main:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;

    pthread_t threadid;
    pthread_attr_t attr;

    ::pthread_attr_init( &attr );
    ::pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    ::pthread_create(&threadid,&attr,run,NULL);

    sleep(6);

    return 0;
}

child.cpp:

#include <sys/prctl.h>
#include <signal.h>
#include <unistd.h>
#include <iostream>

int main() {
    std::cout << "child:" << getpid() << ":" << std::hex << pthread_self() << ":" << std::dec << getppid() << std::endl;
    ::prctl( PR_SET_PDEATHSIG, SIGKILL );
    sleep(6);


    return 0;
}

运行在命令行中执行以下操作:

$ ./parent

同时,运行以下寻子的状态:

$ for i in {1..10000}; do ps aux | grep child ; sleep .5; done

子云解散。 如果你把在孩子使用prctl调用,它不走解散。

在使用prctl页面http://www.kernel.org/doc/man-pages/online/pages/man2/prctl.2.html似乎来形容,这个调用应该叫SIGKILL当父进程死亡,没有父线程。 有没有什么办法让使用prctl杀死孩子当父进程死亡,而不是父线程?

Answer 1:

子进程死亡,因为它接受PR_SET_PDEATHSIG信号时,父线程死亡。 它的意思是,它得到一个信号时,创建它的线程死亡。 所以,如果你希望孩子依赖于父进程(我假设你的意思是当“主”功能去世)从你的父进程的执行主线程叉。 如果你抬头看看手册页的Linux使用prctl(2)手册页 ,他们明确指出它是创造了这个过程中的线程,提供信号给调用(在你的情况下,子)进程:

警告 :在这种情况下,“父”被认为是创造了这个过程中的线程 。 换句话说,该信号将当该线程终止(通过,例如,被发送pthread_exit(3)而不是在所有的线程的父进程终止。

底线:从执行的主线程叉,如果你想让它依赖于父进程的执行。 在简单的话,不创建一个线程来派生子进程,从主线程只是叉它。



Answer 2:

您需要了解线程有两件事情(我的知识是从C,但这种实现似乎符合我用C做了大部分)

一种方法是可以包含多个线程,因为我敢肯定你知道一个大的,重的东西。

我相信这里发生的一切:父线程被杀害,而子线程永远不会收到任何信号,它应该死,也是如此。

你需要确保你的进程结束,它是广播,为所有线程它包含,不只是一个父线程。

这表现很好地从下列图表上POSIX线程LLNL教程 :

我认为,解决方法是只是为了确保你调用在pthread_join当你初始化你的线程。

希望这可以帮助!



文章来源: prctl(PR_SET_PDEATHSIG, SIGNAL) is called on parent thread exit, not parent process exit