0

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);
}
SamL
  • 37
  • 1
  • 10
  • 3
    What resource cleanup do you think is done in the `pthread_cancel()` case that is not done in the `pthread_exit()` case? – John Bollinger Apr 14 '22 at 16:50
  • 2
    To begin with, [`ptjhread_cancel`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cancel.html) might not actually exit a thread, instead it can set a flag that the thread can be exited at the next *cancelation point*. – Some programmer dude Apr 14 '22 at 16:52
  • Also, you appear to be depicting termination from within the thread's entry-point function. Is that the only case you are concerned with, or do you need also to handle cleanup from deeper in the call tree? – John Bollinger Apr 14 '22 at 16:52
  • I am not sure. Please correct me if my question is wrong. I am not sure best way to cancel the tread. https://man7.org/linux/man-pages/man3/pthread_exit.3.html says When a thread terminates, process-shared resources (e.g., mutexes, condition variables, semaphores, and file descriptors) are not released, and functions registered using atexit(3) are not called. – SamL Apr 14 '22 at 17:01
  • I just want to make sure this thread ends plus any resources allocated (I have a socket and this thread it self) for this thread cleared up. May be another question that if I have a mutex should that be unlocked before calling pthread_cancel or pthread_exit. I am not sure which one to use @JohnBollinger, no deeper clean up than this – SamL Apr 14 '22 at 17:08
  • Yes, @SamL, but the exit handlers are not relevant unless the whole process is terminating, and `pthread_cancel()` does not do anything about process-shared resources that `pthread_exit()` does not also do. Generally speaking, thread cancellation is almost always to be avoided. Clean thread termination, whether via `pthread_exit()` or via returning from the entry-point function (which have slightly different semantics) is the way to go. – John Bollinger Apr 14 '22 at 17:09

1 Answers1

1

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.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157