-2

Based on this question: Timeout for thread.join() (ManuelAtWork's answer) I tried to implement a timeout for my std::threads:

std::vector<std::shared_ptr<TestFlow>> testFlowObjects;
std::thread workerThreads[MAX_PARALLEL_NR]; // maximum of 32 threads
std::vector<std::future<void>> helperThreads;

for(int readerCounter=0; readerCounter<GetNumberOfReader(); readerCounter++)
{
    testFlowObjects.push_back(std::make_shared<TestFlow>(m_logFiles));

    testFlowObjects.back()->SetThreadID(readerCounter);
    testFlowObjects.back()->SetTestResults(m_testResultsVector); // vector of int
    workerThreads[readerCounter] = std::thread(&TestFlow::DoWork, testFlowObjects.back());
}

// wait for all threads
for(int threadCount=0; threadCount<GetNumberOfReader(); threadCount++)
{
    // use helper threads to be able to join with timeout
    helperThreads.push_back(std::async(std::launch::async, &std::thread::join, &workerThreads[threadCount]));
    helperThreads.back().wait_for(std::chrono::seconds(5)); // 5 sec
}

It works fine if I use a join instead of the std::future helper thread code, but I can't wait infinite!

With std::future approach it seems not all threads are finished and I got: R6010: abort() has been called

Any ideas how to do it correctly?

I think I have to change it like this:

if(helperThreads.back().wait_for(std::chrono::seconds(5)) == std::future_status::timeout) // WHAT SHOULD I DO HERE???
Community
  • 1
  • 1
leon22
  • 5,280
  • 19
  • 62
  • 100
  • I guess this is not the version your're talking about? Where do you join your workerThreads? What's the purpose of the futures? – Superlokkus Mar 03 '16 at 16:15
  • 1
    **Show a complete example.** Did you join the worker threads? Why are you waiting for 5 seconds in the loop, what's the point of that? It means you wait before you even launch the next task. Surely you want to launch all tasks, then wait for them. Why are you asking about waiting for `std::thread` when you only wait for `std::future` objects? – Jonathan Wakely Mar 03 '16 at 19:15
  • @JonathanWakely If I join the threads it waits until the thread finished but I have to exit after a defined time (5 sec was only for testing -> nothing real) Did you read the answer of ManuelAtWork? His approch use a helper thread to finish the worker thread, but I have to adapt it to several threads (look at my example)! – leon22 Mar 04 '16 at 06:49
  • @Superlokkus Did you read the question? Everything is described and I don't understand why you downvote it?! (it's not helpful to post more code) – leon22 Mar 04 '16 at 12:18
  • Obviously it's not that only I think, further clarification is needed in your question. I've down voted it, because IMHO you did not take not much effort in making answering your question easier. See @JonathanWakely comments. And my points are still: The code where you join the worker threads is needed, describe with your own words what are you intends to do with the seperate parts of you question. So no work in the futures?! Are you just trying to use them for synchronization?! Don't just throw "I think it's all in the other question" (obviously it's not) – Superlokkus Mar 04 '16 at 13:38
  • 1
    But you do `helperThreads.back().wait_for(std::chrono::seconds(5));` **inside** the loop, so you launch a new thread to wait for an earlier thread, then wait 5 seconds, then launch another thread, then wait 5 seconds, then launch another thread, then wait 5 seconds ... that means you wait 5 x GetNumberOfReader seconds in total! Did you look at the accepted answer to the other question? – Jonathan Wakely Mar 04 '16 at 13:44

1 Answers1

0

In short and a recommendation

The approach you posted (ManuelAtWork's answer) is a work around, to use the waiting communication semantics of std::future as an approach to wait with a timeout on a std::thread::join. This could also be achieved with communication via condition variables as the accepted answer mentioned. But why start ThreadFunc in a separate std::thread anyway? Just use std::async which will return a future which will execute your ThreadFunci.e. TestFlow::DoWork.

You probably got the abort because you where trying to join, nonjoinable threads, or because you didn't join some explicit (when moving a new one, in the destructor of the old std::thread) at the position

workerThreads[readerCounter] = std::thread(&TestFlow::DoWork, testFlowObjects.back());

Background/problem

If you want to still use a std::thread you have to do the communication and waiting between the threads by yourself. That implies tasks and problems of many kind (stopping, joining, waiting, thread pooling). The workarounds you linked assumes, you have some other means to terminate a thread. (by communication)

Superlokkus
  • 4,731
  • 1
  • 25
  • 57