我有一个进程子进程(用fork创建),我想在父进程中知道它死了,并做了些什么。在handle函数中我想使用成员类函数,所以我必须将指针传递给"这个"。
我想过两个方面:
选项1:
使用sigaction;
static RpcCmd* rpcCmdPtr = nullptr;// global pointer to save class
主要:
rpcCmdPtr = this;
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = **sigchldHdl**;
sigaction(SIGCHLD, &act, 0)
/* SIGCHLD handler. */
void **sigchldHdl**(int sig)
{
if(rpcCmdPtr != nullptr)
{
rpcCmdPtr->sigHandler(sig);
}
}
void RpcCmd::sigHandler(int sig)
{ // here are some code...}
选项2:
使用另一个线程,将指针传递给"这个"作为参数,并在那里使用signalsfd;
static void * sigThread(void * arg)
{
rpcCmd* rpcCmdPtr = static_cast<rpcCmd*>(arg)
sigprocmask(SIG_BLOCK, &mask, NULL)
/* Create a file descriptor from which we will read the signals. */
sfd = signalfd (-1, &mask, 0);
while (1) {
struct signalfd_siginfo si;
res = read (sfd, &si, sizeof(si));
if (si.ssi_signo == SIGCHLD)
// more code ...
}
我想知道 WHAT 是最好的方式,为什么?
提前致谢。
答案 0 :(得分:3)
仔细阅读signal(7)和signal-safety(7)(并记住大多数C ++标准库 - 包括new
,containers等......都是基于非异步信号安全函数,如malloc
,所以你通常不能从信号处理程序调用这些C ++函数)
你忘记了更便携的选项3:
在流程初始化时,创建一个pipe(7)(到&#34;自我&#34;流程)
在输入event loop之前安装该管道的读处理程序(它将read(2)个字节)
安装(使用sigaction(2))信号的信号处理程序,只需write(2)一个或几个字节进入管道。请注意,write
async-signal-safe。
这种方法由Qt提出,请参见其Calling Qt Functions From Unix Signal Handlers页面。
BTW,许多事件循环库(通常高于poll(2) ...)已经处理SIGCHLD
答案 1 :(得分:1)
option 1
是邪恶的。
只能在信号处理程序中调用async-signal-safe函数。在信号处理程序中无法调用许多函数,例如malloc
free
和printf
信号处理程序必须是可重入的,RpcCmd::sigHandler
可能不可重入