I use pthread_create(&thread1, &attrs, //... , //...); and need if some condition occured need to kill this thread how to kill this ?
First store the thread id
pthread_create(&thr, ...)
then later call
pthread_cancel(thr)
However, this not a recommended programming practice! It's better to use an inter-thread communication mechanism like semaphores or messages to communicate to the thread that it should stop execution.
Note that pthread_kill(...) does not actually terminate the receiving thread, but instead delivers a signal to it, and it depends on the signal and signal handlers what happens.
There are two approaches to this problem.
Use a signal: The thread installs a signal handler using sigaction() which sets a flag, and the thread periodically checks the flag to see whether it must terminate. When the thread must terminate, issue the signal to it using pthread_kill() and wait for its termination with pthread_join(). This approach requires pre-synchronization between the parent thread and the child thread, to guarantee that the child thread has already installed the signal handler before it is able to handle the termination signal;
Use a cancellation point: The thread terminates whenever a cancellation function is executed. When the thread must terminate, execute pthread_cancel() and wait for its termination with pthread_join(). This approach requires detailed usage of pthread_cleanup_push() and pthread_cleanup_pop() to avoid resource leakage. These last two calls might mess with the lexical scope of the code (since they may be macros yielding { and } tokens) and are very difficult to maintain properly.
(Note that if you have already detached the thread using pthread_detach(), you cannot join it again using pthread_join().)
Both approaches can be very tricky, but either might be specially useful in a given situation.
I agree with Antti, better practice would be to implement some checkpoint(s) where the thread checks if it should terminate. These checkpoints can be implemented in a number of ways e.g.: a shared variable with lock or an event that the thread checks if it is set (the thread can opt to wait zero time).
Take a look at the pthread_kill() function.
pthread_exit(0)
This will kill the thread.
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.
(This question might be somewhat related to pthread_exit in signal handler causes segmentation fault) I'm writing a leadlock prevention library, where there is always a checking thread doing graph stuff and checks if there is deadlock, if so then it signals one of the conflicting threads. When that thread catches the signal it releases all mutex(es) it owns and exits. There are multiple resource mutexes (obviously) and one critical region mutex, all calls to acquire, release resource lock and do graph calculations must obtain this lock first. Now there goes the problem. With 2 competing (not counting the checking thread) threads, sometimes the program deadlocks after one thread gets killed. In gdb it's saying the dead thread owns critical region lock but never released it. After adding break point in signal handler and stepping through, it appears that lock belongs to someone else (as expected) right before pthread_exit(), but the ownership magically goes to this thread after pthread_exit()..The only guess I can think of is the thread to be killed was blocking at pthread_mutex_lock when trying to gain the critical region lock (because it wanted another resource mutex), then the signal came, interrupting the pthread_mutex_lock. Since this call is not signal-proof, something weird happened? Like the signal handler might have returned and that thread got the lock then exited? Idk.. Any insight is appreciated!
pthread_exit is not async-signal-safe, and thus the only way you can call it from a signal handler is if you ensure that the signal is not interrupting any non-async-signal-safe function.
As a general principle, using signals as a method of communication with threads is usually a really bad idea. You end up mixing two issues that are already difficult enough on their own: thread-safety (proper synchronization between threads) and reentrancy within a single thread.
If your goal with signals is just to instruct a thread to terminate, a better mechanism might be pthread_cancel. To use this safely, however, the thread that will be cancelled must setup cancellation handlers at the proper points and/or disable cancellation temporarily when it's not safe (with pthread_setcancelstate). Also, be aware that pthread_mutex_lock is not a cancellation point. There's no safe way to interrupt a thread that's blocked waiting to obtain a mutex, so if you need interruptability like this, you probably need either a more elaborate synchronization setup with condition variables (condvar waits are cancellable), or you could use semaphores instead of mutexes.
Edit: If you really do need a way to terminate threads waiting for mutexes, you could replace calls to pthread_mutex_lock with calls to your own function that loops calling pthread_mutex_timedlock and checking for an exit flag on each timeout.
i am making a small project which will be incorporated into larger project. basically what it does is keeps track of threads that are created by way of adding them to a main struct which keeps track of what the thread does (its main function) and its pthread_t id. the other struct keeps track of the data to be passed to the function and the element number of where the pthread_t id is stored inside threads[]. its a bit micky mouse and it jumps around a bit but it all works besides when it is time to kill the thread. i get no segfaults and no errors and the program finishes fine, but the thread does not get killed when pthread_kill() is called (the function returns 0 meaning no error and it worked) although the thread continues to run until the main application returns.
pthread_kill() will not kill a thread. The only difference with kill() is that the signal is handled by the designated thread and not handled while that thread has the signal masked (see pthread_sigmask()). A signal like SIGTERM will by default still terminate the entire process.
If you are considering to call pthread_exit() from a signal handler, you should probably use pthread_cancel() instead.
Cancellation is safe if all code that may be cancelled cooperates (or the code that calls it disables cancellation for the time). Most libraries do not care about this, though.
A safer method is to ask the thread to exit without any force, such as by sending a special message to it (if the thread normally processes messages).
Alternatively, don't bother to kill any threads and just call _exit(), _Exit() or quick_exit().
From http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_kill.html
As in kill(), if sig is zero, error checking is performed but no signal is actually sent.
so the following
pthread_kill(threads[i].tID, 0);
Wont actually kill the thread. You need to use an actual signal to kill a thread. A list of signals can be found here:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/signal.h.html
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 am trying to create a wrapper on Linux which controls how many concurrent executions of something are allowed at once. To do so, I am using a system wide counting semaphore. I create the semaphore, do a sem_wait(), launch the child process and then do a sem_post() when the child terminates. That is fine.
The problem is how to safely handle signals sent to this wrapper. If it doesn't catch signals, the command might terminate without doing a sem_post(), causing the semaphore count to permanently decrease by one. So, I created a signal handler which does the sem_post(). But still, there is a problem.
If the handler is attached before the sem_wait() is performed, a signal could arrive before the sem_wait() completes, causing a sem_post() to occur without a sem_wait(). The reverse is possible if I do the sem_wait() before setting up the signal handler.
The obvious next step was to block signals during the setup of the handler and the sem_wait(). This is pseudocode of what I have now:
void handler(int sig)
{
sem_post(sem);
exit(1);
}
...
sigprocmask(...); /* Block signals */
sigaction(...); /* Set signal handler */
sem_wait(sem);
sigprocmask(...); /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);
The problem now is that the sem_wait() can block and during that time, signals are blocked. A user attempting to kill the process may end up resorting to "kill -9" which is behaviour I don't want to encourage since I cannot handle that case no matter what. I could use sem_trywait() for a small time and test sigpending() but that impacts fairness because there is no longer a guarantee that the process waiting on the semaphore the longest will get to run next.
Is there a truly safe solution here which allows me to handle signals during semaphore acquisition? I am considering resorting to a "Do I have the semaphore" global and removing the signal blocking but that is not 100% safe since acquiring the semaphore and setting the global isn't atomic but might be better than blocking signals while waiting.
Are you sure sem_wait() causes signals to be blocked? I don't think this is the case. The man page for sem_wait() says that the EINTR error code is returned from sem_wait() if it is interrupted by a signal.
You should be able to handle this error code and then your signals will be received. Have you run into a case where signals have not been received?
I would make sure you handle the error codes that sem_wait() can return. Although it may be rare, if you want to be 100% sure you want to cover 100% of your bases.
Are you sure you are approaching the problem correctly? If you want to wait for a child terminating, you may want to use the waitpid() system call. As you observed, it is not reliable to expect the child to do the sem_post() if it may receive signals.
I know this is old, but for the benefit of those still reading this courtesy of Google...
The simplest (and only?) robust solution to this problem is to use a System V semaphore, which allows the client to acquire the semaphore resource in a way which is automatically returned by the kernel NO MATTER HOW THE PROCESS EXITS.