Signals Set
- Many signal-related system calls need to be able to represent a group of different signals.
Initialize a signal set: sigemptyset()
and sigfillset()
- A signal set must be initialize using 1 in these 2 system calls
Add and remove a signal: sigaddset()
and sigdelset()
Check member: sigismember()
Other non-standard system calls
The Signal Mask (blocking Signal delivery)
-
For each process, the kernel maintains a
signal mask
—a set of signals whose delivery to the process is currently blocked. If a signal that is blocked is sent to a process, delivery of that signal is delayed until it is unblocked by being removed from the process signal mask. -
A signal may be added to the signal mask in the following ways:
sigaction()
: adding the signal that caused its invocation or additional set of signalssigprocmask()
: can be used at any time to explicitly add signals to, and remove signals from, the signal mask.
sigprocmask()
- Used to fetch and/or change the
signal mask
of the calling thread.
Explain:
The how
argument determines the changes that sigprocmask() makes to the signal mask:
SIG_BLOCK
: The set of blocked signals is the union of the current set (oldset
) and theset
argument.SIG_UNBLOCK
: The signals in the signal set pointed to byset
are removed from the signal mask. Unblocking a signal that is not currently blocked doesn’t cause an error to be returnedSIG_SETMASK
: The signal set pointed to byset
is assigned to the signal mask (oldset
=set
)
Note: If we want to retrieve the signal mask without changing it, then we can specify
NULL
for the set argument, in which case the how
argument is ignored.
Pending Signals
If a process receives a signal that it is currently blocking, that signal is added to the
process’s set of pending signals. When (and if) the signal is later unblocked, it is
then delivered to the process. To determine which signals are pending for a process, we can call sigpending()
.
- The mask of pending signals is returned in
set
- Note that set of pending signals is only a mask; it indicates whether or not a signal has occurred, but not how many times it has occurred. In other words, if the same signal is generated multiple times while it is blocked, then it is recorded in the set of pending signals, and later delivered, just once
Example
- Consider this example:
sig_sender.c
andsig_receiver.c
- First run: run
sig_receiver.c
with arg 15 so it will sleep 15s (all signals are blocked)
- Second run: run
sig_receiver.c
without arg so no signal is blocked.
- From the output above, we can see that even though one million signals were sent, only one was delivered to the receiver. Even if a process doesn’t block signals, it may receive fewer signals than are sent to it. This can happen if the signals are sent so fast that they arrive before the receiving process has a chance to be scheduled for execution by the kernel, with the result that the multiple signals are recorded just once in the process’s pending signal set