An asynchronous signal is an external event that interrupts a running program independently of its current instruction. A termination request or exceeded deadline can arrive while an operation is in an intermediate state. A synchronous signal, by contrast, arises from a particular faulting instruction, such as division by zero or an invalid memory access. section 19.6
A signal handler is fallback code invoked when a signal occurs. C provides signal handlers as an abstraction over hardware and software interrupts; the underlying faults and their locations vary across platforms. Unlike an exceptional condition detected by the program and handled with setjmp/longjmp, a signal can originate outside the program’s control. section 19.6 section 15.5
Installing a handler
The declarations `sh_handler* signal(int, sh_handler*);` and `int raise(int);` show two operations associated with signals. In an example setup, `sh_enable(i, signal_handler)` is called for successive known signal numbers. Installation is not guaranteed for every number: an attempted installation for `SIGKILL` reports `Invalid argument`. section 19.6
Figure 19.3 Control flow after an interrupt return jumps to the position where the interrupt occurred
The control-flow figure shows execution returning to the position where an interrupt occurred. section 19.6
TAKEAWAY: An asynchronous handler may run when the interrupted execution environment is in an intermediate state. Observe the C library’s context restrictions: calling `signal` in a multithreaded program is not allowed, so a function that uses it can become unsuitable when linked into a program that uses threads. section 19.6 section 15.3.3
#if ATOMIC_LONG_LOCK_FREE > 1
/**
** @brief Keep track of the number of calls into a
** signal handler for each possible signal.
**
** Don't use this array directly.
**
** @see sh_count to update this information.
** @see SH_PRINT to use that information.
**/
extern _Atomic(unsigned long) sh_counts[];
/**
** @brief Use this in your signal handler to keep track of the
** number of calls to the signal @a sig.
**
** @see sh_counted to use that information.
**/
inline
void sh_count(int sig) {
if (sig < sh_known) ++sh_counts[sig];
}
inline
unsigned long sh_counted(int sig){
return (sig < sh_known) ? sh_counts[sig] : 0;
}
#else
This conditional listing counts handler calls with an atomic array when `ATOMIC_LONG_LOCK_FREE > 1`; it illustrates a deliberately limited operation performed by a handler. section 19.6


