我正在编写一个可以表示为简单生产者-消费者问题的应用程序。
生产者任务可以划分为多个单独的问题,每个问题都在一棵树中产生新的叶子。让调用函数负责该“ DoJob” 。这个想法是为N个> N(例如N = 100,M = 4)的M个线程创建N个作业插槽的异步线程队列(使用boost:asio :: io_service)。给定新数据集,该线程队列用于创建和扩展树。
完成所有生产者作业后,唤醒消费者以进行优化。该功能称为'DoOptimization'。
简而言之:多个异步线程产生数据。完成所有生产者作业后,我需要运行消费者作业以优化生产数据。
问题是只有在完成所有生产者作业之后,如何才能使消费者开始工作才能进行同步。
我当时正在考虑使用条件变量作为同步工具。
main()
{
AsyncThreadPool thPool;
Forest forest; // data struture for trees
std::mutex mtx;
std::condition_variable cond_var;
new_data_block = GetNewDataBlock();
while(new_data_block)
for(auto data : new_data_block)
{
// initiating single producer job
thPool.AddToQueue(std::bind(&DoJob, std::ref(data), std::ref(forest)), &cond_var);
}
std::unique_lock<std::mutex> lock(mtx);
cond_var.wait(lock,[&thPool](){return thPool.IsQueueEmpty();}); //@JulianH
// consumer
DoOptimization(std::ref(forest));
// wait for new data
new_data_block = GetNewDataBlock();
}
}
使用简化的队列方法:
bool
AsyncThreadPool::AddToQueue(Task task, std::condition_variable cv)
{
if(queue_slots == 0)
return false;
--queue_slots;
// post wrapped job to a queue
io_service_.post(Wrapper(task, cv)); // also using std::bind here
return true
}
void
AsyncThreadPool::Wrapper(Task task, std::condition_variable cv)
{
task();
++queue_slots;
if(queue_slots == N)
{
cv.notify_one();
}
}
bool
AsyncThreadPool::IsQueueEmpty()
{
return queue_slots == N;
}
我正在寻找解决该问题的最佳/最佳/最经典的解决方案。我没有在这里“嫁给” condition_variable。
在给定的示例中,我还担心在设置notify
之前调用wait
的危险。