In C ++ 11, how can I immediately leave a function when a signal is detected?

In C ++ 11, I have several functions that should stop as soon as possible (and return to the caller) every time this unix signal is received. At first glance, the exception that occurs when a signal is received and intercepted only in the caller’s function seems an obvious solution.

void sighandler(int sig) { throw new myexc(); } void caller(void) { try { callee1(); callee2(); } catch (myexc e) { ... } } 

But safe portable signal processing is quite limited, since changing the value of volatile sig_atomic_t seems to be the only correct one in the signal handler. But I don't want my code to get littered with checking if the sig_atomic_t file has changed or not.

 void sighandler(int sig) { vol = 1; } void callee1(void) { do_stuff(); if (vol == 1) return; do_other_stuff(); if (vol == 1) return; do_something_again(); ... } 

Having a thread waiting for a change in value, then throwing an exception that must be caught by another thread is also not an acceptable solution.

How can I do this in a safe, portable and elegant way?

+4
source share
3 answers

You cannot throw an exception from a signal handler.

Not all operating systems actually have the appropriate stack frame needed to expand the stack. The best you can do is set a flag and then check this in your application.

To prevent your code from being executed with tests.
You can submit your application to Reactor and then register the actual work with the reactor. Before the reactor does a new job, it checks to see if the signal flag is set.

  Reactor workList; workList.add(&callee1); workList.add(&callee2); workList.run(); 

Then inside Reactor ;

  while(notSignalled() && !list.empty()); { list.head().run(); } 
+4
source

Are you sure the exception is allowed in the handler? They are completely independent of the program flow. This is also a poor design - you should only use exceptions in truly exceptional circumstances.

In addition, the full granularity of callee1 a must? Most likely, the function spends most of its time only on a few code fragments, so there should not be a need for a large number of checks for the return condition.

+2
source

You can not. In general, the only way to ensure fast termination of a thread is to quickly terminate the process that contains it. (Posix allows a little more than the standard C in the signal: you can call abort() or _exit() , for example. But not exit() .) Otherwise ... the signals are asynchronous, and there is a possibility that some internal structures data (for example, a stack frame) are not in a coherent state.

+1
source

All Articles