Reputation: 85341
I have a thread pool which executes tasks asynchronously. But I need to wait for a certain task to complete before proceeding (running the task in current thread is not allowed, the task must be run by a worker thread).
What's the easiest way to achieve this using C++11 or Boost?
pool.enqueue([]() {
std::this_thread::sleep_for(2s); // task 1
// notify task 1 completion???
std::this_thread::sleep_for(2s); // task 2
});
// wait until task 1 is complete???
Upvotes: 1
Views: 1265
Reputation: 85341
Going to answer my own question.
I ended up using a future:
std::packaged_task<int()> task1([]() {
std::this_thread::sleep_for(2s); // task 1
return 1;
});
std::future<int> task1result = task1.get_future();
std::thread thread1([&]() {
task1();
std::this_thread::sleep_for(2s); // task 2
});
int rc1 = task1result.get();
printf("task1 complete: %d\n", rc1);
thread1.join();
printf("thread complete\n");
And no, there is no chance for a deadlock since there is no cyclic dependency between the threads (the waiting thread is not part of the pool).
Upvotes: 0
Reputation: 393019
If you have a thread pool, either the pool should handle the dependencies or you should chain the continuation task from the first task directly.
Otherwise, the pool can deadlock. Imagine just for example a pool with 1 thread. It would block indefinitely. Same can occur with many threads given enough task inter dependencies.
Upvotes: 1
Reputation: 485
You can use mutex and wait_for/wait_until
You can look example
Upvotes: 0
Reputation: 7357
Use std::condition_variable:
std::mutex m;
bool task1_done=false;
std::condition_variable cond_var;
pool.enqueue([&cond_var, &task1_done]() {
std::this_thread::sleep_for(2s); // task 1
// notify task 1 completion
task1_done=true;
cond_var.notify_one();
std::this_thread::sleep_for(2s); // task 2
});
// wait until task 1 is complete
std::unique_lock<std::mutex> lock(m);
while( !task1_done ) {
cond_var.wait(lock);
}
Upvotes: 0