people. For a academic exercise i have to implement a program in c for nix platform which is to synchronize multiple processes through signal handling, using only signal,pause,kill and fork basic functions.
I searched google and have not found any clear example: I hope the wisdom of one of you will light my way.
Thanks!
pause doesn't return until a signal is received. The basic design is thus:
fork to create the necessary workers
catch SIGINT in each worker. The handler sets a flag meaning the process should exit after finishing it's current job.
each process does work while it can, then pauses. Repeat unless SIGINT is received (test before & after pause).
when one process has work available for another process, it signals the other process with SIGCONT
when there is no more work for a process, signal it with SIGINT.
This doesn't quite include synchronized access to shared data. To do that, you could add an additional rule:
when a process signals another that work is available, it should pause
Of course, this rather defeats the purpose of concurrent programming.
Since most system calls are interrupted by signals (causing them to return -1, with errno set to EINTR), you'll have to handle this contingency, repeating each affected system call until it's successful. For example:
while ((readCount = read(...)) < 0 && errno == EINTR) {}
One important thing to be aware of is that Linux (at least, and possibly many other Unices) can collapse multiple signals of the same type into a single instance. So if you send a process one signal of value x, that process is guaranteed to receive it; but if you send 2 or more signals of value x, the process is only guaranteed to receive at least one of those signals.
Also, signals are not guaranteed to be received in the order they are sent.
(Why? Under the hood, Linux maintains a bitmask for each process recording which outstanding signals have been sent. Whenever a process is woken up by the scheduler, signal handlers for all outstanding signals are run, in some arbitrary order.)
What all this means is that signals are generally inappropriate for synchronising processes. They only work reliably when time intervals between signals are large with respect to the interval between wake-up times of the receiving process. And if a process spends a lot of time blocked, wake-up events can be arbitrarily far apart.
Conclusion: don't using signals for IPC.
Related
I want to know why these two signals cannot be caught, blocked, or ignored in a process?
The remaining signal's action can be altered by using signal().
What is the difference between this two signal and remaining signal?
If you talk about why they are blocked then the reasons are already mentioned by #Adam B..However I would like to show some internal structure. Its not that you can't really block these two signal. Only KERNEL has the ability to do it, not us.
In the implementation of signal.h, you can see there is a line like this
#define SIG_KERNEL_ONLY_MASK (rt_sigmask(SIGKILL) | rt_sigmask(SIGSTOP))
This shows that these two signals are only maskable by kernel.
Another macro is wrapped around it
#define sig_kernel_only(sig) (((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
which is later used in signal.c..
one function called do_sigaction is returning EINVAL when it receives any signal having negative value or any signals which are not to be handled other than kernel.
check out this
if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig)))
return -EINVAL;
Obviously the system is more intricate than we can think but this is just a glimpse to show that only KERNEL is allowed to handle those signals. Not us. Other than this, there is nothing magical in the implementation of the function.
#R Sahu also talked about a very important aspect of this. The root users should also be restricted to perform certain operations which can be harmful for the system.
Moreover some unresponsive or erroneous applications can be terminated when you have no choice or options to kill it..Use SIGKILL or SIGSTOP with caution..because most of the time these doesn't handle memory cleanup and other housekeeping stuffs well...use these two only when you have no other options..SIGTERM is more popular here
These are handled by kernel. They are used to kill unresponsive tasks(applications).
When your application is itself unresponsive, there should be some way to exit the application. As your task cannot handle anything at this state, there should be a way signal is sent to the unresponsive task but is not handled by the unresponsive task itself.
SIGKILL and SIGSTOP are used for these purposes.
That is why man page says
"The signals SIGKILL and SIGSTOP cannot be caught, blocked, or
ignored."
These are handled by Kernel for you. There are other ample number of signals/Real time signals that you can use for your specific needs.
I am creating a relatively simple multiple process program to learn about signals and signal handling in Linux using C. I have several processes handling signals (I use sigaction to assign handlers) that are sent to all processes in the process group and one tracking process that displays some information after a certain number of signals are detected.
My question is this. How do I reliably display console output from the tracking process? This process needs to display the current number of signals detected and I know printf() isn't good to call from a signal handler. I know I can use write(), but I am not sure I can put variable values into this to display, and I think this system call can be interrupted by signals.
Could you give me a simple example with 3 processes (one generating the signal (parent), 1 handling the signal (child 1) and one reporting info on the signals (child 2)), or explain how this reporter process should handle the output with values of global shared variables?
Thanks
See How to avoid using printf() in a signal handler? for some information about what can be done in a signal handler.
I can't give you a 'simple' example for your 3 process request because the scenario you outline is incredibly complex — how on earth is the third process going to know about what signals the first process sent to the second process? Signals are very crude; there is very little information available other than 'a signal was sent' (slightly more if you use the sa_sigaction member of the struct sigaction and SA_SIGINFO flag when calling the sigaction() function). For most practical purposes, what you ask for can't be done.
If you're going to get close to your scenario, then maybe the method is to set up a shared memory segment in the parent which both children have access to. The second child (signal receiver) can then copy information into the shared memory when it receives a signal, while the third child copies the information out of shared memory and writes it. You'll need to look to see what coordinating functions (if any) are available to a signal handler function — the x-ref'd question has answers which cover this point (and the answer looks like 'none', or only crude ones like open() or mkdir()). Curiously, the POSIX standard does not list function such as strcpy() or memcpy() as signal-safe.
As to 'how to reliably display console output', what is your process going to do while waiting for signals to arrive? You can arrange for the signal handler to set a flag, and the looping code can arrange to check the flag, format and write the data (with standard I/O even; this isn't in a signal handler any more), before going back to waiting for the next signal to arrive.
Hi does anyone know a way to send signal SIGUSR1/2 without loss to another pid ?
the problem is when i put kill(pid, SIGUSR1) in a while loop, my other program recieve only few of them, its seems there is a loss and i have to wait between two calls to kill().
Im actually forced to used usleep() in my loop in order to receive all the SIGUSR signals ive sent.
I'd like to recieve all of them as fast as it is possible.
Thx.
You need to use sigaction() rather than signal() because sigaction() can control which signals are blocked while the current signal is being handled. Also, your receiver has to process each signal received; that is relatively costly compared to sending a signal, so your killer (signalling) process can outrun the 'killed' (receiving) process with ease. You should think about why you are needing to send so many signals. They are a mechanism to use in special circumstances.
There is no way for guaranteed delivery of exactly same amount of signals. If you send two or more SIGUSR1 while other process blocked and can't handle first of them, or processing previous instance of this signal, or have this signal blocked, all but one signals are lost: there is bitmask for pending signals in kernel, not array of counters.
You can only hope to receive as much of them as possible.
There are the so-called real-time signals. These have a queue and unless you overflow the queue you are guaranteed to receive one signal for each signal sent. These are the signals in the range 34-64 or to be portable, SIGRTMIN - SIGRTMAX.
However, if your assignment is to use SIGUSR1 and SIGUSR2 then maybe you're supposed to be learning about unreliable data transmission. The same sort of problems happen in electrical circuits. If a latch is already set by an electrical signal then a second signal has no effect until the latch is read and cleared. This is why serial and parallel ports have clocks and/or acknowledgement signals.
Without keeping a list of current threads, I'm trying to see that a realtime signal gets delivered to all threads in my process. My idea is to go about it like this:
Initially the signal handler is installed and the signal is unblocked in all threads.
When one thread wants to send the 'broadcast' signal, it acquires a mutex and sets a global flag that the broadcast is taking place.
The sender blocks the signal (using pthread_sigmask) for itself, and enters a loop repeatedly calling raise(sig) until sigpending indicates that the signal is pending (there were no threads remaining with the signal blocked).
As threads receive the signal, they act on it but wait in the signal handler for the broadcast flag to be cleared, so that the signal will remain masked.
The sender finishes the loop by unblocking the signal (in order to get its own delivery).
When the sender handles its own signal, it clears the global flag so that all the other threads can continue with their business.
The problem I'm running into is that pthread_sigmask is not being respected. Everything works right if I run the test program under strace (presumably due to different scheduling timing), but as soon as I run it alone, the sender receives its own signal (despite having blocked it..?) and none of the other threads ever get scheduled.
Any ideas what might be wrong? I've tried using sigqueue instead of raise, probing the signal mask, adding sleep all over the place to make sure the threads are patiently waiting for their signals, etc. and now I'm at a loss.
Edit: Thanks to psmears' answer, I think I understand the problem. Here's a potential solution. Feedback would be great:
At any given time, I can know the number of threads running, and I can prevent all thread creation and exiting during the broadcast signal if I need to.
The thread that wants to do the broadcast signal acquires a lock (so no other thread can do it at the same time), then blocks the signal for itself, and sends num_threads signals to the process, then unblocks the signal for itself.
The signal handler atomically increments a counter, and each instance of the signal handler waits until that counter is equal to num_threads to return.
The thread that did the broadcast also waits for the counter to reach num_threads, then it releases the lock.
One possible concern is that the signals will not get queued if the kernel is out of memory (Linux seems to have that issue). Do you know if sigqueue reliably informs the caller when it's unable to queue the signal (in which case I would loop until it succeeds), or could signals possibly be silently lost?
Edit 2: It seems to be working now. According to the documentation for sigqueue, it returns EAGAIN if it fails to queue the signal. But for robustness, I decided to just keep calling sigqueue until num_threads-1 signal handlers are running, interleaving calls to sched_yield after I've sent num_threads-1 signals.
There was a race condition at thread creation time, counting new threads, but I solved it with a strange (ab)use of read-write locks. Thread creation is "reading" and the broadcast signal is "writing", so unless there's a thread trying to broadcast, it doesn't create any contention at thread-creation.
raise() sends the signal to the current thread (only), so other threads won't receive it. I suspect that the fact that strace makes things work is a bug in strace (due to the way it works it ends up intercepting all signals sent to the process and re-raising them, so it may be re-raising them in the wrong way...).
You can probably get round that using kill(getpid(), <signal>) to send the signal to the current process as a whole.
However, another potential issue you might see is that sigpending() can indicate that the signal is pending on the process before all threads have received it - all that means is that there is at least one such signal pending for the process, and no CPU has yet become available to run a thread to deliver it...
Can you describe more details of what you're aiming to achieve? And how portable you want it to be? There's almost certainly a better way of doing it (signals are almost always a major headache, especially when mixed with threads...)
In multithreaded program raise(sig) is equivalent to pthread_kill(pthread_self(), sig).
Try kill(getpid(), sig)
Given that you can apparently lock thread creation and destruction, could you not just have the "broadcasting" thread post the required updates to thread-local-state in a per-thread queue, which each thread checks whenever it goes to use the thread-local-state? If there's outstanding update(s), it first applies them.
You are trying to synchronize a set of threads.
From a design pattern point of view the pthread native solution for your problem would be a pthread barrier.
I've been trying to understand the intricacies of how POSIX threads and POSIX signals interact. In particular, I'm interested in:
What's the best way to control which thread a signal is delivered to (assuming it isn't fatal in the first place)?
What is the best way to tell another thread (that might actually be busy) that the signal has arrived? (I already know that it's a bad idea to be using pthread condition variables from a signal handler.)
How can I safely handle passing the information that a signal has occurred to other threads? Does this need to happen in the signal handler? (I do not in general want to kill the other threads; I need a far subtler approach.)
For reference about why I want this, I'm researching how to convert the TclX package to support threads, or to split it up and at least make some useful parts support threads. Signals are one of those parts that is of particular interest.
What's the best way to control which thread
a signal is delivered to?
As #zoli2k indicated, explicitly nominating a single thread to handle all signals you want handled (or a set of threads each with specific signal responsibilities), is a good technique.
What is the best way to tell another thread (that might actually be busy)
that the signal has arrived?[...]
How can I safely handle passing the information that a signal has occurred
to other threads? Does this need to happen in the signal handler?
I won't say "best," but here's my recommendation:
Block all desired signals in main, so that all threads are inherit that signal mask. Then, fashion the special signal receiving thread as a signal-driven event loop, dispatching newly arrived signals as some other intra-thread communication.
The simplest way to do this is to have the thread accept signals in a loop using sigwaitinfo or sigtimedwait. The thread then converts the signals somehow, perhaps broadcasting a pthread_cond_t, waking up other threads with more I/O, enqueuing a command in an application-specific thread-safe queue, whatever.
Alternatively, the special thread could allow signals to be delivered to a signal handler, unmasking for delivery only when ready to handle signals. (Signal delivery via handlers tends to be more error-prone than signal acceptance via the sigwait family, however.) In this case, the receiver's signal handler performs some simple and async-signal-safe action: setting sig_atomic_t flags, calling sigaddset(&signals_i_have_seen_recently, latest_sig), write() a byte to a non-blocking self-pipe, etc. Then, back in its masked main loop, the thread communicates receipt of the signal to other threads as above.
(UPDATED #caf rightly points out that sigwait approaches are superior.)
According to the POSIX standard all threads should appear with the same PID on the system and using pthread_sigmask() you can define the signal blocking mask for every thread.
Since it is allowed to define only one signal handler per PID, I prefer to handle all signals in one thread and send pthread_cancel() if a running thread need to be cancelled. It is the preferred way against pthread_kill() since it allows to define cleanup functions for the threads.
On some older systems, because of the lack of proper kernel support, the running threads may have different PID from the parent thread's PID. See FAQ for signal handling with linuxThreads on Linux 2.4.
Where I'm at so far:
Signals come in different major classes, some of which should typically just kill the process anyway (SIGILL) and some of which never need anything doing (SIGIO; easier to just do async IO right anyway). Those two classes need no action.
Some signals don't need to be dealt with immediately; the likes of SIGWINCH can be queued up until it is convenient (just like an event from X11).
The tricky ones are the ones where you want to respond to them by interrupting what you're doing but without going to the extent of wiping out a thread. In particular, SIGINT in interactive mode ought to leave things responsive.
I've still got to sort through signal vs sigaction, pselect, sigwait, sigaltstack, and a whole bunch of other bits and pieces of POSIX (and non-POSIX) API.
IMHO, Unix V signals and posix threads do not mix well.
Unix V is 1970. POSIX is 1980 ;)
There are cancellation Points and if you allow signals and pthreads in one application, you will eventually end up writing Loops around each call, which can surprisingly return EINTR.
So what I did in the (few) cases where I had to program multithreaded on Linux or QNX was, to mask out all signals for all (but one) threads.
When a Unix V Signal arrives, the process Switches the stack (that was as much concurrency in Unix V as you could get within a process).
As the other posts here hint, it might be possible now, to tell the System, which posix thread shall be the victim of that stack switching.
Once, you managed to get your Signal handler thread working, the question remains, how to transform the signal information to something civilized, other threads can use. An infrastructure for inter-thread communications is required. One pattern, useful is the actor pattern, where each of your threads is a target for some in-process Messaging mechanism.
So, instead of canceling other threads or killing them (or other weird stuff), you should try to marshall the Signal from the Signal context to your Signal handler thread, then use your actor pattern communications mechanisms to send semantically useful messages to those actors, who need the signal related Information.