prctl(PR_SET_PDEATHSIG, SIGNAL) 在父线程退出时调用,而不是在父进程退出时调用
prctl(PR_SET_PDEATHSIG, SIGNAL) is called on parent thread exit, not parent process exit
我有一个分叉到子进程的进程。如果父进程存在,则子进程不应存在。
因此,我在子进程中调用::prctl(PR_SET_PDEATHSIG, SIGKILL)
,如果父进程死亡,则将其杀死。
最终发生的是父线程调用pthread_exit
,该线程最终成为杀死子进程的催化剂。
这是我的代码:
家长.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;
}
儿童.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 手册页似乎描述了此调用应在父进程(而不是父线程)死亡时调用SIGKILL
。
有没有办法让 prctl 在父进程而不是父线程死亡时杀死孩子?
子进程死亡,因为它在父线程死亡时接收PR_SET_PDEATHSIG
信号。这意味着当创建它的线程死亡时,它会得到一个信号。因此,如果您希望子进程依赖于父进程(我假设您的意思是当"main"函数死亡时),请从父进程的执行主线程中分叉。如果你在 Linux prctl(2) 手册页中查找手册页,它们特别指出是线程创建了这个进程,将信号传递给调用进程(在你的例子中是子进程):
警告:在这种情况下,"父"被认为是 创建此进程的线程。 换句话说,信号 将在该线程终止时发送(例如,通过
pthread_exit(3)
),而不是在 父进程终止。
底线:如果您希望主线程依赖于父进程的执行,请从主线程分叉。简单来说,不要创建一个线程来分叉子进程,只需从主线程分叉它。
相关文章:
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 链接器命令失败,macOS 上的退出代码为 1(使用 -v 查看调用)
- clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用) - 体系结构的未定义符号 x86_64:
- 如何修复 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- C++::在构造函数退出之前通过指针调用成员函数
- Xcode:链接器命令失败,退出代码为 1(使用 -v 查看调用)[C++]
- 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用):在 Macbook 上
- clang:错误:链接器命令失败,C++代码中的退出代码为 1(使用 -v 查看调用)
- Xcode 10.0:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 如何使功能"run"工作。程序在调用运行时退出
- 在析构函数中调用退出不会杀死 QThread?
- QT Q_PROPERTY错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- ld:找不到体系结构x86_64 clang 的符号:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 当我要退出应用程序时,如何在QT中自动调用destructor
- 流媒体错误:在退出上一个呼叫之前,请再次调用InternetStatusCallback
- 如何在线程创建和退出时调用函数?
- Xcode链接器错误:链接器命令失败,退出代码为1(使用-v查看调用)
- ld:1 个重复符号用于架构x86_64 clang: 错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- C++,Win32:如何在 main() 退出后调用函数
- 如果线程在调用pthread_join之前退出,该怎么办