开发者

About the delivery of standard signals

By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, the开发者_JAVA百科n 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..


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().


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.


One signal is processed at a time, in each thread. While the signal handler runs, all other signals are automatically blocked.

So it's not possible to queue multiple of the same signal to a single thread. Many different signals, however, can appear in the queue.

I supposed it's possible for a signal handler to unblock some signals before it exits, in this case you would risk overflow of the signal stack (the call stack used for signal handlers, not the signal queue) if the signals were being generated faster than they could be processed.


If signal is delivered while same signal is being handled, handler would be invoked again right after return from current invocation, so there will be multiple signal deliveries.

Of course, if signal is sent multiple times while still processing first one, only one signal will be queued and only one repeated handler invocation will occur.

Signals are marked "pending" in proc struct in kernel, so there is separate signal bitmask for each process and only one signal of each kind (SIGBUS, SIGINT, SIGUSR1, etc) can be pending, but several different signals may be pending simultaneously.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜