3

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.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
ManiAm
  • 1,759
  • 5
  • 24
  • 43
  • Possible duplicate of [How do I terminate a thread in C++11?](http://stackoverflow.com/questions/12207684/how-do-i-terminate-a-thread-in-c11) – Fred Larson Apr 26 '16 at 18:26
  • 1
    If you kill a thread uncooperatively how can you give any guarantees about your program? – imreal Apr 26 '16 at 18:28

1 Answers1

5

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.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • **instead of killing the thread, provide the thread task with a function or atomic variable that says when the worker should kill itself.** ok. I will use this approach. – ManiAm Apr 26 '16 at 19:55
  • but what to do if the thread is running a blocking library function and cant repeatedly check whether to die? – ihsan Dec 19 '22 at 16:36
  • @ihsan then use a different process. If you are running external code that could be in an arbitrary state, there is no safe way to kill the thread. A seperate process lets resources get cleaned up (assuming sane OS). Within a process there are no similar mechanisms. – Yakk - Adam Nevraumont Dec 19 '22 at 17:09
  • @Yakk-AdamNevraumont how can i do that in windows, – ihsan Jan 12 '23 at 10:46
  • 1
    @ihsan I would google "create process windows" and look at the results? – Yakk - Adam Nevraumont Jan 12 '23 at 14:24