【问题标题】:Passing data from caller thread to the method in another boost::thread将数据从调用者线程传递到另一个 boost::thread 中的方法
【发布时间】:2013-05-21 12:24:50
【问题描述】:

关于 C++ 中的并发性(使用 Boost 线程),我有一个相当菜鸟的问题,我还没有找到明确的答案。我有一个在单独的线程中运行的工作人员类。我在开始时初始化工作人员只编程一次。这个工人是“懒惰的”,只有当它从调用线程接收到它时才进行一些数据编码。在工人中我有一个公共方法:

void PushFrame(byte* data);

将数据推送到 std::stack 成员变量,以便每次将新数据对象推送到那里时工作人员都可以访问它。

我不明白这种交互通常是如何完成的?我可以从调用者线程调用 PushFrame() 并传递参数吗?还是我必须以某种特殊方式访问工作人员中的方法?

【问题讨论】:

    标签: c++ multithreading boost concurrency


    【解决方案1】:

    通常您使用 producer-consumer-queue 来完成此类工作。

    每当工作线程用完工作时,他wait()s 在boost::condition_variable 上,它受到与保存工作线程数据的堆栈相同的boost::mutex 保护(您可能希望在此处使用队列代替以尽量减少不公平工作安排的风险)。

    您的PushFrame() 函数现在在将新数据插入堆栈时对该条件变量调用notify_one()。这样,工作线程将真正休眠(即操作系统调度程序可能不会给它任何时间片),直到有实际工作要做。

    这里最容易出错的是互斥锁的锁定,它同时保护了堆栈和 condition_variable。除了避免数据结构上的竞争之外,您还需要注意 condition_variable 不会错过通知调用,因此可能会在实际上有更多可用工作时卡住等待。

    class Worker {
       void PushFrame(byte* data)
       {
           boost::lock_guard<boost::mutex> lk(m_mutex);
           // push the data
           // ...
           m_data_cond.notify_one();
       }
       void DoWork()
       {
           while(!done) {
               boost::unique_lock<boost::mutex> lk(m_mutex);
    
               // we need a loop here as wait() may return spuriously
               while(is_out_of_work()) {
                   // wait() will release the mutex and suspend the thread
                   m_data_cond.wait(lk);
                   // upon returning from wait() the mutex will be locked again
               }
    
               // do work from the queue
               // ...
           }
       }
       boost::mutex m_mutex;
       boost::condition_variable m_data_cond;
     [...]
    };
    

    【讨论】:

    • notify_one 是 condition_variable 的一部分。工人应该继承它吗?你能添加一些简单的概念例子吗?谢谢!
    • condition_variable 应该是您的 Worker 类的成员。在答案中添加了一个小代码示例。
    • @ComicSansMS 我认为评论 do work from the queue 应该在循环结束时(检查工作后),否则队列可能是空的。这可能发生在第一次运行 DoWork()(如果尚未发布任何工作)或者如果有多个 Worker 线程并且在循环结束时释放锁后另一个线程获取互斥锁。
    • is_out_of_work() 我想检查队列中是否有要编码的数据?
    • @MichaelIV 这就是目的,是的。
    猜你喜欢
    • 2018-05-19
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多