use*_*199 5 c++ multithreading fork execv
我有一个分支到子进程的进程。如果父进程存在,则子进程不应存在。因此,如果父进程死亡,我在子进程中调用:: 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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
在命令行上运行以下命令:
$ ./parent
Run Code Online (Sandbox Code Playgroud)
同时,运行以下命令以查找子代的状态:
$ for i in {1..10000}; do ps aux | grep child ; sleep .5; done
Run Code Online (Sandbox Code Playgroud)
孩子去世了。如果您在child中取出prctl调用,则该调用不会失效。
http://www.kernel.org/doc/man-pages/online/pages/man2/prctl.2.html上的prctl页面似乎描述了当父进程死亡而不是父线程死亡时,此调用应调用SIGKILL 。当父进程(而不是父线程)死亡时,有什么方法可以使prctl杀死子进程?
子进程死亡是因为它PR_SET_PDEATHSIG在父线程死亡时收到信号。这意味着当创建它的线程死亡时,它会收到一个信号。因此,如果您希望子进程依赖于父进程(我假设您的意思是“主”函数死亡时)从父进程执行的主线程分叉。如果您在Linux prctl(2) 手册页中查找手册页,它们会明确指出它是创建此进程的线程,将信号传递给调用(在您的情况下为子)进程:
警告:在这种情况下,“父”被认为是创建此进程的 线程。换句话说,该信号将在该线程终止时发送(例如,通过
pthread_exit(3)),而不是在父进程中的所有线程终止后发送。
底线:如果您希望它依赖于父进程的执行,则从执行的主线程分叉。简单来说,不要创建一个线程来 fork 子进程,只需从主线程 fork 即可。