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
Related
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.
My question is similar to this one. But after viewing all its answers, I still don't know what kind of safety guarantee one can get with pthread_cancel(). So I would like to ask a more specific question:
Say that pthread_cancel() is called on a pthread_t variable, named my_thread, is it possible that by the time pthread_cancel(my_thread) is executed, the actual thread corresponding to my_thread has already been terminated somehow, and the kernel recycled the value of my_thread for another newly created thread, such that by executing pthread_cancel(my_thread), another unintended thread gets killed?
The value can't be "recycled" until the thread is detached or joined. As long as you didn't do either of those things, it's safe to call pthread_cancel, even if the thread already terminated.
The question is about race conditions involving pthread_cancel(). POSIX requires that function to be thread safe in the specific, limited sense in which it uses that term, but that doesn't really speak to the question at hand. The key details are specified in XSH 2.9.2, as #R.. observed earlier in a comment. In particular:
The lifetime of a thread ID ends after the thread terminates if it was
created with the detachstate attribute set to PTHREAD_CREATE_DETACHED
or if pthread_detach() or pthread_join() has been called for that
thread. A conforming implementation is free to reuse a thread ID after
its lifetime has ended. If an application attempts to use a thread ID
whose lifetime has ended, the behavior is undefined.
So an application is permitted to re-use thread IDs whose lifetime has ended, but that's really a side issue because if you attempt to use a stale one then the behavior is undefined, whether the ID has been reused or not. And of course, one of the innumerable possible manifestations of UB that could ensue in the case described is indeed that a different thread is cancelled than the one you meant to cancel, regardless of whether the thread ID has been reused.
The lifetime of a thread ID ends when the thread it identifies terminates if that thread was created detached, or when it is passed to either pthread_detach or pthread_join if the thread was created joinable. It is entirely possible to have a race between that and the execution of pthread_cancel. If the thread was created joinable then you need at least three threads total for that, but if it was created detached then you don't need any other than the one calling pthread_cancel and a separate one being cancelled. Either way pthread_cancel is risky.
The accepted answer to the question you linked is misleading, at best, but #DavidSchwartz's comment on it is much more useful, even if I don't think it accurately reflects the specification in every detail. Here is how I would put it:
It is safe to cancel a thread with pthread_cancel if one of these cases holds:
the thread was created joinable, and it is certain that it cannot have been detached or joined before the pthread_cancel call completes, or
the thread was created detached, and it is certain that it cannot have terminated, nor have been passed to pthread_join or pthread_attach (regardless of the success of these calls) before the pthread_cancel call completes.
It is not safe (i.e. it risks UB) to attempt to cancel
a thread that was created joinable, via the thread ID provided by pthread_create, if it is possible for that thread to be detached or joined before the pthread_cancel call completes, or
a thread that was created detached, if it is possible for that thread to terminate or have pthread_join or pthread_detach called on it before the pthread_cancel call completes.
It is unclear whether it is safe to cancel a thread that was created joinable and later detatched, via a thread ID obtained from pthread_self() after the detachment, if it is certain that neither pthread_join nor pthread_detach can have been called on that thread ID before the `pthread_cancel completes.*
*One could interpret the specifications to imply that under those circumstances, pthread_self returns a thread ID whose lifetime has already ended, so that the cancellation would definitely produce UB. But there are at least a couple different contrary interpretations, and under any of those, there is no defined condition under which the lifetime of the thread ID from pthread_self ends before the end of the program, leaving it safe to cancel the thread via that ID at any time.
I have read that TerminateThread() in WinAPI is dangerous to use.
Is pthread_kill() in Linux also dangerous to use?
Edit: Sorry I meant pthread_kill() and not pthread_exit().
To quote Sir Humphrey Appleby, the answer is "yes, and no".
In and of itself calling pthread_exit() is not dangerous and is called implicitly when your thread exits its method. However, there are a few "gotchas" if you call it manually.
All cleanup handlers are called when this is called. So if you call this method, then access some memory that the cleanup handlers have cleaned up, you get a memory error.
Similarly, after this is called, any local and thread-local variables for the thread become invalid. So if a reference is made to them you can get a memory error.
If this has already been called for the thread (implicitly or explicitly) calling it again has an undefined behaviour, and
If this is the last thread in your process, this will cause the process to exit.
If you are careful of the above (i.e. if you are careful to not reference anything about the thread after you have called pthread_exit) then it is safe to call call manually. However, if you are using C++ instead of C I would highly recommend using the std::thread class rather than doing it manually. It is easier to read, involves less code, and ensures that you are not breaking any of the above.
For more information type "man pthread_exit" which will essentially tell you the above.
Since the question has now been changed, I will write a new answer. My answer still remains "yes and no" but the reasons have changed.
pthread_kill is somewhat dangerous in that it shares the potential timing risks that is inherent in all signal handling systems. In addition there are complexities in dealing with it, specifically you have to setup a signal handler within the thread. However one could argue that it is less dangerous than the Windows function you mention. Here is why:
The Windows function essentially stops the thread, possibly bypassing the proper cleanup. It is intended as a last resort option. pthread_kill, on the other hand, does not terminate the thread at all. It simply sends a signal to the thread that the thread can respond to.
In order for this to do something you need to have registered in the thread what signals you want it to handle. If your goal is to use pthread_kill to terminate the thread, you can use this by having your signal handler set a flag that the thread can access, and having the thread check the flag and exit when it gets set. You may be able to call pthread_exit from the signal handler (I've never tried that) but it strikes me as being a bad idea since the signal comes asynchronously, and your thread is not guaranteed to still be running. The flag option I mention solves this provided that the flag is not local to the thread, allowing the signal handler to set it even if the target thread has already exited. Of course if you are doing this, you don't really need pthread_kill at all, as you can simply have your main thread set the flag at the appropriate time.
There is another option for stopping another thread - the pthread_cancel method. This method will place a cancel request on the target thread and, if the thread has been configured to be cancellable (you generally do this in the pthread_create, but you can also do it after the fact), then the next time the thread reaches a potential cancellation point (specified by pthread_testcancel but also automatically handled by many system routines such as the IO calls), it will exit. This is also safer than what Windows does as it is not violently stopping the thread - it only stops at well defined points. But it is more work than the Windows version as you have to configure the thread properly.
The Wikipedia page for "posix threads" describes some of this (but not much), but it has a pretty good "See also" and "References" section that will give you more details.
(Working in Win32 api , in C environment with VS2010)
I have a two thread app. The first thread forks the second and waits for a given interval - 'TIMEOUT', and then calls TerminateThread() on it.
Meanwhile, second thread calls NetServerEnum().
It appears that when timeout is reached , whether NetServerEnum returned successfully or not, the first thread get deadlocked.
I've already noticed that NetServerEnum creates worker threads of it's own.
I ultimately end up with one of those threads in deadlock, typically on ntdll.dll!RtlInitializeExceptionChain, unable to exit my process gracefully.
As this to too long for a comment:
Verbatim from MSDN, allow me to use te answer form (emphasis by me):
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:
If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
*If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.
From reading this it is easy to understanf why it is a bad idea to cancel (terminate) a thread stucking in a system call.
A possible alternative approach to the OP's design might be to spawn off a thread calling NetServerEnum() and simply let it run until the system call returned.
In the mean while the main thread could do other things like for example informing the user that scanning the net takes longer as expected.
I am writing a multithreaded program and i have this question:
Suppose that, while executing in the main thread, i want to terminate all
child-threads. I can't just send them a termination signal cause i want them
to free dynamically allocated memory first. Can i define a specific signal handler
function in each thread function that is executed, which in turn is going to call
a cleanup function that i will write to do so? If not how can i accomplish my goal??
Thanks,
Nikos
Look at the man page for pthread_cancel:
When a cancellation requested is acted on, the following steps occur for
thread (in this order):
1. Cancellation clean-up handlers are popped (in the reverse of the order in
which they were pushed) and called. (See pthread_cleanup_push(3).)
2. Thread-specific data destructors are called, in an unspecified order. (See
pthread_key_create(3).)
3. The thread is terminated. (See pthread_exit(3).)
So you can use pthread_cancel from your main, provided you have registered you cleanup handlers correctly using the above functions.
(Do read that man page completely though, it has a lot of important information.)
Edit: (from comments) If you plan on using PTHREAD_CANCEL_DEFERRED and need to insert a cancellation point somewhere in your code, then use pthread_testcancel. This function checks if a cancellation was requested. If that is the case, the cancellation is serviced (i.e. that call never returns). Otherwise it has no effect.
The most robust strategy requires cooperation from the child threads: you set a flag that the threads periodically check and, when the flag is set, free whatever resources they're using and then terminate.
Cancellation (Mat's answer) is the correct and canonical one, but if you want a different approach, you can install a no-op signal handler using sigaction without the SA_RESTART flag and use pthread_kill with whatever signal number you chose in order to interrupt (EINTR) whatever the thread might have been blocked on. Combined with this, aix's answer works.