I was about to add an extra signal handler to an app we have here and I noticed that the author had used sigaction()
to set up the other signal handlers. I was going to use signal()
. To follow convention I should use sigaction()
but if I was writing from scratch, which should I choose?
The difference between sigaction and signal
c++posixsignals
Related Question
- C++ – the effect of extern “C” in C++
- C++ – the difference between const int*, const int * const, and int const *
- The difference between a definition and a declaration
- Difference between malloc and calloc
- C++ – the “–>” operator in C/C++
- Sqlite – Improve INSERT-per-second performance of SQLite
- Linux – the meaning of “POSIX”
- What does the ??!??! operator do in C
Best Solution
Use
sigaction()
unless you've got very compelling reasons not to do so.The
signal()
interface has antiquity (and hence availability) in its favour, and it is defined in the C standard. Nevertheless, it has a number of undesirable characteristics thatsigaction()
avoids - unless you use the flags explicitly added tosigaction()
to allow it to faithfully simulate the oldsignal()
behaviour.signal()
function does not (necessarily) block other signals from arriving while the current handler is executing;sigaction()
can block other signals until the current handler returns.signal()
function (usually) resets the signal action back toSIG_DFL
(default) for almost all signals. This means that thesignal()
handler must reinstall itself as its first action. It also opens up a window of vulnerability between the time when the signal is detected and the handler is reinstalled during which if a second instance of the signal arrives, the default behaviour (usually terminate, sometimes with prejudice - aka core dump) occurs.signal()
varies between systems — and the standards permit those variations.These are generally good reasons for using
sigaction()
instead ofsignal()
. However, the interface ofsigaction()
is undeniably more fiddly.Whichever of the two you use, do not be tempted by the alternative signal interfaces such as
sighold()
,sigignore()
,sigpause()
andsigrelse()
. They are nominally alternatives tosigaction()
, but they are only barely standardized and are present in POSIX for backwards compatibility rather than for serious use. Note that the POSIX standard says their behaviour in multi-threaded programs is undefined.Multi-threaded programs and signals is a whole other complicated story.
AFAIK, bothsignal()
andsigaction()
are OK in multi-threaded applications.Cornstalks observes:
That's interesting. The Linux manual page is more restrictive than POSIX in this case. POSIX specifies for
signal()
:So POSIX clearly specifies the behaviour of
signal()
in a multi-threaded application.Nevertheless,
sigaction()
is to be preferred in essentially all circumstances — and portable multi-threaded code should usesigaction()
unless there's an overwhelming reason why it can't (such as "only use functions defined by Standard C" — and yes, C11 code can be multi-threaded). Which is basically what the opening paragraph of this answer also says.