rustyx
rustyx

Reputation: 85341

C++ / boost : how to signal async task completion?

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

Answers (4)

rustyx
rustyx

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

sehe
sehe

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

Vladislav Mikitich
Vladislav Mikitich

Reputation: 485

You can use mutex and wait_for/wait_until

You can look example

Upvotes: 0

Galimov Albert
Galimov Albert

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

Related Questions