Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminate a thread from outside in C++11

I am running multiple threads in my C++11 code and the thread body is defined using lambda function as following.

// make connection to each device in a separate child thread
std::vector<std::thread> workers;
for(int ii = 0; ii < numDev; ii++)
{    
    workers.push_back(std::thread([=]() {  // pass by value

     // thread body

    }));
}

// detach from all threads
std::for_each(workers.begin(), workers.end(), [](std::thread &t) {
    t.detach();
});

// killing one of the threads here?

I detached from all children threads but keep a reference of each in workers vector. How can I kill one of the threads later on in my code?

Post in here suggests using std::terminate() but I guess it has no use in my case.

like image 971
ManiAm Avatar asked Sep 15 '25 06:09

ManiAm


1 Answers

First, don't use raw std::threads. They are rarely a good idea. It is like manually calling new and delete, or messing with raw buffers and length counters in io code -- bugs waiting to happen.

Second, instead of killing the thread, provide the thread task with a function or atomic variable that says when the worker should kill itself.

The worker periodically checks its "should I die" state, and if so, it cleans itself up and dies.

Then simply signal the worker to die, and wait for it to do so.

This does require work in your worker thread, and if it does some task that cannot be interrupted that lasts a long time it doesn't work. Don't do tasks that cannot be interrupted and last a long time.

If you must do such a task, do it in a different process, and marshall the results back and forth. But modern OSs tend to have async APIs you can use instead of synchronous APIs for IO tasks, which lend themselves to being aborted if you are careful.

Terminating a thread while it is in an arbitrary state places your program into an unknown and undefined state of execution. It could be holding a mutex and never let it go in a standard library call, for example. But really, it can do anything at all.

Generally detaching threads is also a bad idea, because unless you magically know they are finished (difficult because you detached them), what happens after main ends is implementation defined.

Keep track of your threads, like you keep track of your memory allocations, but moreso. Use messages to tell threads to kill themselves. Join threads to clean up their resources, possibly using condition variables in a wrapper to make sure you don't join prior to the thread basically being done. Consider using std::async instead of raw threads, and wrap std::async itself up in a further abstraction.

like image 58
Yakk - Adam Nevraumont Avatar answered Sep 17 '25 20:09

Yakk - Adam Nevraumont