I'm have a pthread function, which sleeps most of the time using usleep()
I would like to send a signal from the main process to the thread to interrupt the sleeping sometimes.
The problem is that I can't find any reference of which signal exactly to send using pthread_kill()
the usleep() man page, states that SIGALRM should not be used together with usleep()
Do I need to use a specific signal, it doesn't matter ?
The tools to synchronize between threads are not signals and usleep (or nanosleep) but combinations of pthread_mutex_t and pthread_cond_t. Just have your thread wait on a condition (this can be done with a timeout) and have your main thread send a "signal" on the condition variable.
usleep returns with EINTR on every signal that's delivered to a thread/process. You'll probably be best off using SIGUSR signals.
Also, usleep is now obsolete : consider using nanosleep instead. As an added bonus, you'll know how much sleep time was remaining at the time of the delivery of the signal.
Related
This request is about PThreads and using conditions or signals to pause/resume a continuous cycle worker thread.
A while ago, I came into this:
https://stackoverflow.com/a/23945651/6421961
Basically, user johnnycrash uses sigwait() to get a thread into a pause state (waiting for external wakening) and pthread_kill(thread_id, USR1) to signal the thread into waking up. He claims it to be faster than using the mutex+condition construct and it appears to be less complex. I am developing a piece of software that would indeed require a thread to sleep until signaled and return to sleep after doing work in an infinite cycle (the eater of a feeder-eater paradigm).
I am using this to have a separate thread waiting for the conclusion of worker threads. In my current implementation, worker threads add their handles to a list protected by a mutex, signal the waiting thread with pthread_kill and finish with pthread_join.
My questions are all related:
How valid is it to actually use pthread_kill()+sigwait() instead of mutex+condition?
In case it is an acceptable solution, what pitfalls/race conditions
should one be aware of?
Would it be better to use pthread_sigqueue() instead of pthread_kill()? Would it actually be able catch signals sent while sigwait() is not running and immediately process them as soon as sigwait() is called?
Last question, derived from some contradicting information I found: Will different threads both paused with sigwait() expecting USR1 be able to be signaled independently, or will only one of them be able to actually catch the signal regardless of which one was signaled?
I will try to answer points 1 and 4.
pthread_kill() + sigqueue() and mutex+condition they both have their own purposes. When you're working with data (i.e. global variable) which is used by multiple threads in that case mutex are more appropriate. But, when you're waiting for an external event (like. network packet) and want to signal your thread based on that event pthread_kill() is more appropriate.
It depends how the signal (USR1) was sent. If it was sent using pthread_kill() or pthread_sigqueue() you can specify which thread you're sending that signal to, the only difference is with pthread_sigqueue() - you can send an additional information with the signal. You can also send signal to specific pid or group-wise signal sending using kill(). So, it largely depends on your need.
I want to wait for a pthread condition variable, but when I get a SIGUSR1 (or any other signal) I want to stop waiting and detect that it stopped waiting because of a signal, not because of a pthread_cond_signal or spurious wakeup. How can I do this?
A reliable way to handle signals in a pthreads program is to mask all the signals you wish to handle in every thread, and create a dedicated signal handling thread that loops around calling sigwaitinfo() (or sigtimedwait()).
The signal handling thread can then use ordinary mutex-protected shared variables and pthread_cond_signal() / pthread_cond_broadcast() wakeups to inform other threads about the signals received.
In your example, the dedicated signal handling thread could set a (mutex-protected) flag indicating that SIGUSR1 has been received, then signal the condition variable that your thread is waiting on. The waiting thread just needs to check the signal flags in addition to its other shared state in the loop around pthread_cond_wait().
I'm curious if I am able to do the following with the unistd c function alarm(int signal)
Having my main.... and for each thread hat is created to initializate a SIGALRM with the function, which should close my thread in case of activating. Is this possible? or 1 SIGALRM / main is legal only?
Each thread in a process has an independent signal mask, which
indicates the set of signals that the thread is currently blocking. A
thread can manipulate its signal mask using pthread_sigmask(3). In a
traditional single-threaded application, sigprocmask(2) can be used to
manipulate the signal mask.
from man 7 signal.
The problem is that alarm works per process, not per thread, so if the sigmask of the threads is the same, you can't really know which one will receive the signal.
OK, so first, the alarm() is actually taking an unsigned int value which is the number of seconds before it expires. So your example int signal isn't the correct implementation of alarm(), just FYI.
As far as this goes:
for each thread that is created to initialization a SIGALRM
The SIGALRM that is generated is done so for the process not per thread, so you will have to catch the alarm and have some internal strategy to know which thread you raised it for and handle that accordingly. Once you have your handler, you can raise the alarm over and over again, however keep in mind:
Alarm requests are not stacked;
So you'll have to do this one at a time. It's still possible, but not totally stright forward as you were hoping.
For very rough example of what I'm talking about:
you have a "manager" which keeps track of requests
thread 1 tells the manager it needs to handle something in 10s
the manager "records" this and calls set alarm(10)
thread 2 tells the manager it needs to be woken up in 3 seconds
the manager calls alarm(0) to kill the alarm, calls alarm(3) then notes that once that goes off it needs to call alarm(7) to finish thread 1's sleep time
in your alarm handler you just call the manager and let it know an alarm went off and it will wake the appropriate thread (2) then reset the alarm for the next one.
I want to make a thread sleep for an indefinite amount of time. The reason I want to do this is because my program only takes action when it receives a signal and has nothing to do in the primary thread. Therefore, all processing is done inside the signal handler. How can I sleep for an indefinite amount of time?
I believe you're looking for the pause function:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pause.html
You could do something like: for (;;) pause();
If you're just doing something on another thread, simply call pthread_join on that thread and it will pretty much block "forever". You could achieve the same effect using a condition variable.
Use semaphores!
Have your thread blocked on a semaphore by using sem_wait. Once you need to wake your thread signal the semaphore by using sem_post from another thread.
POSIX provides the sigsuspend function to wait for a signal. (As mentioned in another answer, pause works as well.)
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.