C ++ 11 gets a job completed by one of two algorithms

I have two algorithms for solving problem X () .

How can I get the thread running for algorithm 1 and the thread running for algorithm 2 and wait for the first algorithm to finish, after which I kill it and continue?

I saw that the join from std::thread will make me wait until it ends, but I can not do join for both threads, otherwise I will wait until both of them are completed. I want to release both of them and wait until one of them is completed. What is the best way to achieve this?

+5
source share
3 answers

First, do not kill the losing algorithm. Just let it run to the end and ignore the result.

Now, the closest thing to what you requested is to have the variable mutex + condvar + result (or, more likely, two results, one for each algorithm).

The code would look like

 X result1, result2; bool complete1 = false; bool complete2 = false; std::mutex result_mutex; std::condition_variable result_cv; // simple wrapper to signal when algoN has finished std::thread t1([&]() { result1 = algo1(); std::unique_lock lock(result_mutex); complete1 = true; result_cv.notify_one(); }); std::thread t2([&]() { result2 = algo2(); std::unique_lock lock(result_mutex); complete2 = true; result_cv.notify_one(); }); t1.detach(); t2.detach(); // wait until one of the algos has completed int winner; { std::unique_lock lock(result_mutex); result_cv.wait(lock, [&]() { return complete1 || complete2; }); if (complete1) winner=1; else winner=2; } 

Other mechanisms, including future / promise, require the main thread to be busy. The only alternative without waiting for a wait is to move the processing after success to call_once : in this case, the main thread should just join both children, and the second child will simply return when it finishes processing and realizes that it is lost.

+2
source

You cannot kill threads in C ++ 11, so you need to organize their demise.

This can be done by associating them with the variable std::atomic<bool> and getting the winner std::call_once() to set the return value and mark the rest of the threads.

Perhaps this is something like this:

 std::once_flag once; // for std::call_once() void algorithm1(std::atomic<bool>& done, int& result) { // Do some randomly timed work for(int i = 0; !done && i < 3; ++i) // end if done is true std::this_thread::sleep_for(std::chrono::seconds(std::rand() % 3)); // Only one thread gets to leave a result std::call_once(once, [&] { done = true; // stop other threads result = 1; }); } void algorithm2(std::atomic<bool>& done, int& result) { // Do some randomly timed work for(int i = 0; !done && i < 3; ++i) // end if done is true std::this_thread::sleep_for(std::chrono::seconds(std::rand() % 3)); // Only one thread gets to leave a result std::call_once(once, [&] { done = true; // stop other threads result = 2; }); } int main() { std::srand(std::time(0)); std::atomic<bool> done(false); int result = 0; std::thread t1(algorithm1, std::ref(done), std::ref(result)); std::thread t2(algorithm2, std::ref(done), std::ref(result)); t1.join(); // this will end if t2 finishes t2.join(); std::cout << "result : " << result << '\n'; } 
+3
source

The new C ++ 11 standard offers some methods to solve these problems using, for example, futures, promises.

Please see http://de.cppreference.com/w/cpp/thread/future and When is it a good idea to use std :: promise with other std :: thread mechanisms? .

+2
source

Source: https://habr.com/ru/post/1205766/


All Articles