多个生产者一个消费者同步

时间:2019-02-22 14:31:05

标签: c++ multithreading

我正在编写一个可以表示为简单生产者-消费者问题的应用程序。

  1. Producer是一种增长非二叉树结构的算法,代表特定的关联问题。
  2. 消费者的任务是选择“最佳”关联方案,并优化树以适应该方案(削减不必要的分支)。

生产者任务可以划分为多个单独的问题,每个问题都在一棵树中产生新的叶子。让调用函数负责该“ 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的危险。

0 个答案:

没有答案