Reputation: 53
I have a process child (created with fork), I want to know in the parent where it dies, and do there something. In the handle function I want to use member-class function, so I have to pass pointer to "this".
I have thought on two way:
Option 1:
use sigaction;
static RpcCmd* rpcCmdPtr = nullptr;// global pointer to save class
in the main:
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...}
Option 2:
use another thread, pass pointer to "this" as argument, and use there signalfd;
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 ...
}
I want to know WHAT is the best way, and WHY?
Thanks in advance.
Upvotes: 0
Views: 554
Reputation: 1
Read carefully signal(7) and signal-safety(7) (and remember that most of C++ standard library -including new
, containers, etc...- is based upon non async-signal-safe functions like malloc
, so you usually cannot call these C++ functions from a signal handler)
You forgot the more portable option 3:
at process initialization, create a pipe(7) (to "self" process)
before entering your event loop install a read handler for that pipe (it would read(2) bytes from it)
install (using sigaction(2)) a signal handler for your signal that simply write(2) one or a few bytes into the pipe. Notice that write
is async-signal-safe.
This approach is proposed by Qt, see its Calling Qt Functions From Unix Signal Handlers page.
BTW, many event loop libraries (often above poll(2)...) do handle already SIGCHLD
Upvotes: 3
Reputation: 5275
option 1
is evil.
only async-signal-safe function can be called inside a signal handler. And lots of function can't be called inside a signal handler, eg malloc
free
and printf
signal handler must be reentrant, your RpcCmd::sigHandler
probably is not reentrant
Upvotes: 1