Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Killing a std::thread

I have a program that creates a thread that listens for an event. There is a situation in which this thread will never receive this event, and I must terminate it. I know how to catch the case in which it will not receive this event.

I've created a std::thread, however I found nothing on how to terminate the thread. I've tried calling

t.detach()

And then letting the destructor so the work, but I cannot clean up resources allocated by the thread this way.

My questions are: 1. Is there a way to send a SIGKILL or equivalent to a std::thread to kill it? And 2. Is there a way to catch this signal from within the thread to clean up resources?

The question asked (and answered) How do I terminate a thread in C++11? doesn't answer my question as I want to terminate the thread from it's parent, not from within the thread.

Furthermore, my problem is that my worker thread can be either waiting for a blocking system call (i.e., an incoming packet) or a conditional variable, which is why this is tricky.

like image 624
Blue Granny Avatar asked Jan 25 '23 20:01

Blue Granny


2 Answers

  1. Is there a way to send a SIGKILL or equivalent to a std::thread to kill it?

There is no such equivalent; at least a standard one.

  1. Is there a way to catch this signal from within the thread to clean up resources?

There is no standard way in C++ to signal a thread.

POSIX has pthread_kill that can be used to signal a thread. Note that "stop", "continue", or "terminate" signals affect the entire process, so this is not for what you're asking exactly.

However, asynchronous signal handlers are limited on what they can do, and resource cleanup won't be possible. What you should do is let the thread know that it should terminate, and let it stop and cleanup voluntarily.

thread that listens for an event.

Solution depends on what kind of listening we are considering. If it is a condition variable, you can set an atomic boolean to request termination and wake up the thread by notifying.

If listening is a blocking system call, solution is a bit trickier. The great thing about raising a signal, is that it interrupts blocking system calls. You can use the handler to set a volatile sig_atomic_t variable that the thread can read and voluntarily return. The interruption may give your thread a chance to check the variable before resuming the wait. The caveat is that we must turn that may into a guarantee:

You must register the signal handler using sigaction (standard POSIX function; not standard C++) with SA_RESTART unset. Otherwise depending on system defaults, the system call might resume instead of returning.


Another approach is to send the event that the other thread is waiting for. This may be simpler or trickier than above depending on what kind of event we are considering. For example, when listening on a socket, it is typically possible to connect to that socket.


There is a proposal to introduce std::jthread thread wrapper into a future C++ standard, which offers a portable way to request a thread to stop. Unfortunately, I don't know what guarantees there would be regarding blocking system calls.

like image 95
eerorika Avatar answered Jan 28 '23 09:01

eerorika


Generally killing thread is the undesired behaviour, you want to initiate the thread , do the necessary implementation based on the condition, and if the condition don't satisfy then you could exit it cleanly. Probably use std::condition_variable ... and set the condition from main thread so that child could exit based on certain condition.

like image 23
Pawan Adhikari Avatar answered Jan 28 '23 10:01

Pawan Adhikari