Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About the delivery of standard signals

Tags:

c

linux

signals

By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued.

I think the above description is not so clear and causing ambiguity to me:

what if the specific signal is not blocked , will multiple instances of the same signal be queued?

Where is the signal queued,a process specific location or a global location?

How is the queued signals handled, will it be possible that two signals are being processed at the same time,or it's guaranteed signals will be processed one by one?

So it's actually 3 questions here..

like image 940
Je Rog Avatar asked Jun 14 '11 13:06

Je Rog


2 Answers

what if the specific signal is not blocked , will multiple instances of the same signal be queued?

It depends on whether the SA_SIGINFO flag has been set for the signal using the sigaction structure and sigaction() function, and whether your system has a valid definition for _POSIX_REALTIME_SIGNALS (modern Linux kernels do). If both instances are true, then any arriving signals that fit those two conditions will be queued in a per-process queue until they are delivered or accepted up to the limits imposed by the operating system for the number of items in a given signal's queue. After that point, any other signal arriving for that signal-type are dropped.

If either one of those situations is not true, then only the currently arriving signal is handled, and any other signals of the same signal type that arrive while the current signal handler is running are dropped. Also if you are blocking the signal, and two or more signals arrive at the process and are not delivered, they are merged together into a single signal event. But again, this is only if the above two conditions are not met ... otherwise multiple signal events of the same type are queued.

One more note ... the two conditions stated are for the POSIX specification, but Linux will queue any real-time signal, even if SA_SIGINFO is not set for that signal. So that would mean any signal corresponding to the range SIGRTMIN and SIGRTMAX.

Where is the signal queued,a process specific location or a global location?

It's stored in a per-process queue.

How is the queued signals handled, will it be possible that two signals are being processed at the same time,or it's guaranteed signals will be processed one by one?

This depends on how you setup the signal handler with the sigaction struture and sigaction() function. It is not guaranteed that any other signals will be blocked while your signal handler runs. There is a signal mask that can be set within the sigaction struture determining what signals are blocked while your signal handler runs. The signal itself is blocked until the signal handler completes, but a different signal can interrupt your current signal handler if it is not blocked by the signal mask set for the signal handler set in your sigaction strurcture. Therefore anything you do in a signal handler should be async-safe, and you should not be calling any non-async-safe functions in your signal handler like fprintf(), etc. So it is guaranteed that the signal itself is handled in FIFO order (i.e., a signal will not interrupt itself), but other signals can interrupt your current signal handler if you have not intentionally blocked them. Keep in mind that setting up a signal mask inside your signal handler in an attempt to block other signals from interrupting your handler is a very bad idea, and is not an atomic operation, so don't do that. If you want other signals blocked while your signal handler runs, provide a signal mask in the sigaction structure you pass to sigaction().

like image 104
Jason Avatar answered Sep 21 '22 18:09

Jason


It's a bit-mask - notice that standard signals all have values under 32?

Edit 0:

The "queue" for standard signals is just a bit-mask per thread, so once a signal is posted and not yet delivered the given bit is set, and posting the same signal is lost until that bit is cleared, i.e. signal is delivered.

Edit 1:

We can reliably reap child processes because that mechanism does not rely on signals only. Kernel keeps detailed information about process ancestry, and child process does not disappear once it exited, but left in the process table for the parent to reap (that's how we breed zombies, right :). Pending SIGCHLD means "at least one of your children changed state, dip into the kernel to collect the corpses". The race here is not on the signal "queue", but on the process table/tree/whatever and it's the kernel's job to protect it.

like image 35
Nikolai Fetissov Avatar answered Sep 23 '22 18:09

Nikolai Fetissov