【问题标题】:How to implement a blocking processing loop?如何实现阻塞处理循环?
【发布时间】:2020-09-01 07:35:24
【问题描述】:

我想在工作线程中实现一个处理循环,以便它在有东西时处理队列中的数据并阻塞(线程休眠)否则......这甚至可能吗?也应该没有任何明显的延迟。

像这样简单的事情:

std::deque<Foo> queue;

void worker() 
{
    while (active) {
        blockAndWaitForData();

        while (!queue.empty()) {
            doSomething(queue.front());
            queue.pop_front();
        }
    }
}

当然需要锁定队列以及一些其他细节。

如果需要,也可以直接使用 Linux API。

【问题讨论】:

  • condition variables,另外最好使用某种形式的无锁队列(比如boost::lockfree::queue)。
  • 使用std::condition_variable 表示数据的可用性。更好的是,使用existing threadsafe queue implementation
  • 您所要求的有一个名称:您要求的是一个阻塞队列。也就是说,一个队列,其方法会自动阻止尝试访问front 对象的调用者,直到那里有可以访问的对象。

标签: c++ linux multithreading loops c++17


【解决方案1】:

C++11 标准中有一些东西可以满足您的需求。它是condition_variable。它允许您等到其他线程通知它。所以你的工人可以等到生产者这样通知它。请注意,这是一个非常愚蠢的示例,在大多数情况下还不够,但可以为您提供如何做到这一点的要点

std::deque<int> q;
std::mutex m;
std::condition_variable cv;

void worker() {
    while (active) {
        std::deque<int> vals;
        {
            std::unique_lock<std::mutex> l(m);
            cv.wait(l, []{return q.empty();});
            vals = std::move(q);
            q.clear();
        }
        for (const auto& val : vals)
            doSomething(val);
    }
}

void producer() {
    while (active) {
        {
            std::unique_lock<std::mutex> l(m);
            q.push_back(produce());
        }  
        cv.notify_one();
   }
}

【讨论】:

  • 请注意,使用此代码,m 在执行doSomething 期间被锁定,这在实践中可能效率很低。我不确定 OP 是否看到这一点,如果他们不熟悉条件变量。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 2018-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多