How to kill a running thread? [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
kill thread in pthread
Here after a source code containing a launch of thread and then after a while I want to kill it. How to do it ? Without make any change in the thread function
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t test_thread;
void *thread_test_run (void *v) // I must not modify this function
{
int i=1;
while(1)
{
printf("into thread %d\r\n",i);
i++;
sleep(1);
}
return NULL
}
int main()
{
pthread_create(&test_thread, NULL, &thread_test_run, NULL);
sleep (20);
// Kill the thread here. How to do it?
// other function are called here...
return 0;
}

You can use pthread_cancel() to kill a thread:
int pthread_cancel(pthread_t thread);
Note that the thread might not get a chance to do necessary cleanups, for example, release a lock, free memory and so on..So you should first use pthread_cleanup_push() to add cleanup functions that will be called when the thread is cancelled. From man pthread_cleanup_push(3):
These functions manipulate the calling thread's stack of
thread-cancellation clean-up handlers. A clean-up handler is a
function that is automatically executed when a thread is cancelled (or
in various other circumstances described below); it might, for
example, unlock a mutex so that it becomes available to other threads
in the process.
Regarding the question of whether a thread will be cancelled if blocking or not, it's not guaranteed, note that the manual also mentions this:
A thread's cancellation type, determined by pthread_setcanceltype(3),
may be either asynchronous or deferred (the default for new
threads). Asynchronous cancelability means that the thread
can be canceled at any time (usually immediately, but the system does
not guarantee this). Deferred cancelability means that cancellation
will be delayed until the thread next calls a function that is a
cancellation point.
So this means that the only guaranteed behaviour is the the thread will be cancelled at a certain point after the call to pthread_cancel().
Note:
If you cannot change the thread code to add the cleanup handlers, then your only other choice is to kill the thread with pthread_kill(), however this is a very bad way to do it for the aforementioned reasons.

The short answer is this: With the cooperation of the code that thread is running, you may terminate it using any method it supports. Without the cooperation of the code that thread is running, you shouldn't even try it. What if the thread is holding a critical lock when you kill it? What if the thread has allocated memory and there is no other code to free that memory?

Related

Can a thread self-destruct by calling pthread_cancel

When spinning a new thread I am doing few things which that thread needs to consume. If something is wrong I want to cancel, or exit from that thread. I read that pthread_exit does not do resource clean up. So I like to stick with pthread_cancel. Question is can I call pthread_cancel on the same thread. I am aware that I can call pthread_cancel from some other thread but not sure from its own thread. (How to kill a running thread?)
What is the best way to do this?
My code looks like below.
void* my_thread(){
//do this --> go to failure if fails
//do that --> go to failure if fails
//do this too --> go to failure if fails
while(1){
//will read, write or usleep until data is available
}
failure:
pthread_cancel(my_thread_id);
}
Question is can I call pthread_cancel on the same thread.
There is no documented restriction against it, so I expect pthread_cancel(thread_id) to have the same effect when called from a thread whose ID is thread_id as it does when called from any other thread.
However, "the same effect" can be no effect if the thread has cancellation disabled, and it can be a deferred (until the next cancellation point) effect if the thread's cancellation type is PTHREAD_CANCEL_DEFERRED (the default). To have the greatest likelihood of terminating the thread, as quickly as possible, you should:
// ensure that the thread is cancellable
int old_state;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
// perform the cancellation
pthread_cancel(my_thread_id);
// user-defined cancellation point
pthread_testcancel();
With that said, the question seems to be based on a faulty premise:
I read that pthread_exit does not do resource clean up.
That is exactly as true of pthread_cancel() as it is of pthread_exit(). Thread termination by either of those means will cause any registered cancellation handlers to be invoked, which does provide a route for resource cleanup, but neither does any cleanup of process-shared resources other than that.*
Thread cancellation is almost always the wrong thing to do. It is especially the wrong thing for a thread to do to itself, as pthread_exit() is cleaner, safer, and more reliable, and the two have the same cleanup semantics. You do have to take appropriate measures to clean up resources, but that's true either way. pthread_cancel() does not provide any unique shortcuts for that.
* Note: unlike termination via pthread_cancel() or pthread_exit(), returning from the entry-point function does not cause cancellation handlers to run.

How to pthread_barrier_destroy() without waiting for pthread_barrier_wait()

I have a multithreaded application that uses barriers to synchronise worker threads.
At the end of function compute(), threads are cancelled:
...
for(int i=0;i<p; i++){
printf("Thread %lu completed in %d passes\n",threads[i],find_tstat(threads[i])->count);
pthread_cancel(threads[i]);
}
printf("================================================================\n");
return a;
Threads are interrupted in the middle of computation, so they may be in between barriers. This is likely what's causing pthread_barrier_destroy() to hang, is because some barrier_wait() has not returned yet.
The question is; how can I still destroy even if a wait() hasn't returned?
Answer to your question is: you can't.
man pthread_barrier_destroy
The results are undefined if pthread_barrier_destroy() is called when any thread is blocked on the barrier
man pthread_cancel
On Linux, cancellation is implemented using signals.
man pthread_barrier_wait
If a signal is delivered to a thread blocked on a barrier, upon return from the signal handler the thread shall resume waiting at the barrier if the barrier wait has not completed (that is, if the required number of threads have not arrived at the barrier during the execution of the signal handler); otherwise, the thread shall continue as normal from the completed barrier wait. Until the thread in the signal handler returns from it, it is unspecified whether other threads may proceed past the barrier once they have all reached it.
A thread that has blocked on a barrier shall not prevent any unblocked thread that is eligible to use the same processing resources from eventually making forward progress in its execution. Eligibility for processing resources shall be determined by the scheduling policy.
As the question is posed:
The question is; how can I still destroy even if a wait() hasn't returned?
the answer is "you can't", as your other answer explains.
However, with good enough record keeping, you can launch just enough extra threads specifically to wait at the barrier in order to let any other threads already waiting pass through. This would likely be tied together with code and data intended to provide for your threads to be shut down cleanly instead of being canceled, which is also something you should do.
On the other hand, it's pretty easy to roll your own barrier with use of a condition variable and mutex, and the result is more flexible. You still should not be canceling threads, but you can make waits at a hand-rolled barrier such as I describe soft-cancelable. This would be my recommendation.

pthread_cond_wait returns after sign_handler()?

Fellow coders.
If I send a SIGINT signal to a thread stuck on pthread_cond_wait(), when sign_handler() returns, will pthread_cond_wait() return as well?
If not, is there any way to make pthread_cond_wait() return?
If I send a SIGINT signal to a thread stuck on pthread_cond_wait(), when sign_handler() returns, will pthread_cond_wait() return as well?
No.
If not, is there any way to make pthread_cond_wait() return?
No, you're trying to use the wrong tool to solve whatever underlying problem you have.
(Technically, pthread_cond_timedwait() is allowed to return when interrupted by a signal delivery, but it does not do so, at least when using GNU glibc 2.27 on x86-64 running kernel 5.3.0. Yes, I checked.)
How can I fix my problem?
Let's assume that a condition variable is the best option for your use case. (That's just a guess, though; you didn't tell us about your real problem you're trying to solve, only how your chosen solution isn't working.)
Then, the recommended solution is to use a helper thread to catch signals like SIGINT, using sigwaitinfo() or sigtimedwait(). That helper thread can then set a specific volatile sig_atomic_t you_need_to_exit flag, and pthread_cond_signal() or pthread_cond_broadcast() on the relevant condition variables to let them know something important happened. Those waiting on the condition variables should obviously first check the helper flag; and if set, assume that that was the source for the wakeup signal. Usually I name such flags need_to_exit or similar.
The key in such signal handling helper threads is that the signals need to be blocked in all threads (including the handling helper thread itself). It is best to do this in the main thread before creating any other threads, as then the created threads inherit that same signal mask.
The siginfo_t structure contains all kinds of useful information. Most useful is perhaps the .si_pid field, which tells which process (or 0 if kernel) sent the signal. That way, if you use say SIGRTMIN+0 to SIGRTMAX-0 signals for internal purposes, you can ignore them unless they come from the process itself (other threads, .si_pid == getpid()).
Thread cancellation (deferred, at cancellation points; pthread_cond_wait() being a cancellation point) is another option. You can use pthread_cleanup_push() to set/add functions to be run if the thread is cancelled. This basically forcibly kills the target thread, but it can run any cleanup functions it has set up before it dies. You can also defuse any cleanup functions using pthread_cleanup_pop() -- a parameter specifies whether the cleanup function is run and discarded, or just discarded. But, when cancelled, the thread always dies.
Do use pthread_attr_t to limit the stack size to a sane power of two. If you don't have any large arrays or structures on stack (local variables), then something like
#include <limits.h>
#ifndef THREAD_STACK_SIZE
#define THREAD_STACK_SIZE (4 * PTHREAD_STACK_MIN)
#endif
with
sigset_t mask;
pthread_attr_t attrs;
int err;
/* Block SIGINT in this (and all created threads) */
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
err = pthread_sigmask(SIG_BLOCK, &mask, NULL);
if (err) {
fprintf(stderr, "Cannot block signals: %s.\n", strerror(err));
return EXIT_FAILURE;
}
/* Create stack size attribute. */
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
/*
* Create threads, use &attrs for the second parameter.
*/
/* Optional cleanup - it's a good idea to be careful. */
pthread_attr_destroy(&attrs);
should work fine, for both stack size and blocking some signals in all threads (by blocking them first in the thread that creates the other threads; they'll inherit the signal mask).
You can add any other signals to the blocked mask you like, except that SIGKILL and SIGSTOP cannot be blocked, caught, or ignored.
The pthread_attr_t second parameter to pthread_create() is just a collection of settings (or attributes), like configuration; they are not "consumed" by the pthread_create() call. You can use the same set of attributes any number of times. This one contains only the desired stack size. (It does not contain the stack itself, only the desired size.)
The default stack size is very large, typically 8 MiB, which means that a lot of virtual memory is reserved for thread stacks for no good reason, really. Also, it severely limits the number of threads a process can create.
In many ways, having a helper thread for signal handling is easier than actual signal handlers, because only async-signal safe functions are safe to use in a signal handler; whereas in the helper thread, you can use all.

thread cancellation in posix threads

i am using posix threads my question is as to whether or not a thread can cancel itself by passing its own thread id in pthread_cancel function?
if yes then what are its implications
also if a main program creates two threads and one of the thread cancels the other thread then what happens to the return value and the resources of the cancelled thread
and how to know from main program as to which thread was cancelled ..since main program is not cancelling any of the threads
i am using asynchronous cancellation
kindly help
Q1: Yes, a thread can cancel itself. However, doing so has all of the negative consequences of cancellation in general; you probably want to use pthread_exit instead, which is somewhat more predictable.
Q2: When a thread has been cancelled, it doesn't get to generate a return value; instead, pthread_join will put the special value PTHREAD_CANCELED in the location pointed to by its retval argument. Unfortunately, you have to know by some other means that a specific thread has definitely terminated (in some fashion) before you call pthread_join, or the calling thread will block forever. There is no portable equivalent of waitpid(..., WNOHANG) nor of waitpid(-1, ...). (The manpage says "If you believe you need this functionality, you probably need to rethink your application design" which makes me want to punch someone in the face.)
Q2a: It depends what you mean by "resources of the thread".  The thread control block and stack will be deallocated. All destructors registered with pthread_cleanup_push or pthread_key_create will be executed (on the thread, before it terminates); some runtimes also execute C++ class destructors for objects on the stack. It is the application programmer's responsibility to make sure that all resources owned by the thread are covered by one of these mechanisms. Note that some of these mechanisms have inherent race conditions; for instance, it is impossible to open a file and push a cleanup that closes it as an atomic action, so there is a window where cancellation can leak the open file. (Do not think this can be worked around by pushing the cleanup before opening the file, because a common implementation of deferred cancels is to check for them whenever a system call returns, i.e. exactly timed to hit the tiny gap between the OS writing the file descriptor number to the return-value register, and the calling function copying that register to the memory location where the cleanup expects it to be.)
Qi: you didn't ask this, but you should be aware that a thread with asynchronous cancellation enabled is officially not allowed to do anything other than pure computation. The behavior is undefined if it calls any library function other than pthread_cancel, pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED), or pthread_setcancelstate(PTHREAD_CANCEL_DISABLE).
Q1. Yes,thread can cancel itself.
Q2. If one thread cancel another thread , its resources are hang around until main thread
join that thread with pthread_join() function(if the thread is joinable). And if the canceled
thread is not join in main thread resources are free with program ends/terminate.
Q3. I am not sure, but main program don't know which thread was canceled.
thread can cancel any other thread (within the same process) including itself
threads do not have return values (in general way, they can have return status only), resources of the thread will be freed upon cancellation
main program can store thread's handler and test whether it valid or not

thread at exit cleanup

I have an application in which I have 1 main thread which creates 10 different threads for doing some job. At the end of application, when I try to exit, the application is not able to cleanly exit. The stack trace is not that useful, but its showing the crash in function "cancel_deliver()" My first guess is this is some underlying call made while doing the freeing up of resources used by each thread, but not entirely sure.
fyi: The callback function for each thread has a while (1) loop:
Here is the snippet
void main (...)
{
pthread_t tid;
for (int i=0; i<10; i++)
pthread_create(&tid, NULL, xyzCallback, NULL);
}
void xyzCallback(void* data)
{
while (1)
{
////
}
}
void atExit()
{
exit(1);
}
Is there any thing that I can do to free up resrouces used by my thread and cleanly exit?
For this case
If I understand your setup correctly...
One thing you could do is have a set of 'flag' variables, one for each thread (including the main thread). When the main thread is ready to end, set its flag. This flag should be continually checked within the 10 other threads. Once it becomes set, change the flag variable for that specific thread and call pthread_exit. In the main exit method, only terminate once all the flag variables are set.
Assuming your program isn't crashing due to another reason, this should enable all the threads to finish in a controlled manner.
(or use pthread_join in the main exit function, since pthread_exit returns information used by pthread_join)
In general
Use pthread_exit instead of exit(1) to cleanly exit the thread.
From the LLNL POSIX Thread Programming page:
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
Also see the pthread_exit man page.
You need to decide whether your threads (1) need to end in a well defined way (state), or if the latter does not matter (2) take care where and when they could be cancelled (which happens implicitly when the program ends)
Referring 1: A possible way could be to implement an exit condition which will be triggered when the program shall terminate and makes the threads leave their while(1) loop. Before leaving the main loop calling pthread_join() for any pthread_t pthread it received by the calls to pthread_create(). If all threads terminate the main's join loops is left and main ends with all threads terminated already.
Referring 2: This is the more critical case, as depending on the thread functions's code it is not clear where it will be canceled, which could lead to unexpected behaviour. A thread could be cancelled at a so called cancellation point. Some system calls are treated as such.
In any case the thread function does not necessarily need to call pthread_exit() as last statement. This is only necessary if you want to have pthread_join() receive a pointer passed to pthread_exit().

Resources