2

boost 库(在 C++11 标准之前)提供了对线程的支持。作为其支持的一部分,它还提供了“屏障”的实现,这是一个允许同步的简单类。引用boost 网站

“屏障是一个简单的概念。也称为集合点,它是多个线程之间的同步点。屏障是为特定数量的线程(n)配置的,当线程到达屏障时,它们必须等到所有 n 个线程已经到达。一旦第 n 个线程到达屏障,所有等待的线程都可以继续,屏障被重置。

从 Boost 1.54 开始,屏障(等待)的主要功能的实现如下所示:

bool wait()
{
    boost::mutex::scoped_lock lock(m_mutex);
    unsigned int gen = m_generation;

    if (--m_count == 0)
    {
        m_generation++;
        m_count = m_threshold;
        m_cond.notify_all();
        return true;
    }

    while (gen == m_generation)
        m_cond.wait(lock);
    return false;
}

可以看出屏障是可重复使用的:一旦构建,第一次使用后不需要销毁。

我现在的问题是:变量 m_ge​​neration 是干什么用的?我假设 boost 库的作者有理由包含它。每次重置/准备重用屏障时,它都会增加,但目的是什么?它是一个私有变量,因此无法从外部读取。同样的问题可以很容易地在 wait() 函数中使用一个简单的内部 bool 变量来解决,而无需使用私有类变量。

4

1 回答 1

5

简而言之,m_generation需要处理虚假唤醒

生成计数器与条件变量一起使用,以向所有在屏障上等待的线程发出信号,表明它们可以继续进行:

  • 一旦有m_threshold线程到达屏障,它的代数就会增加,并且条件变量会发出信号。这会导致等待线程(即那些较早到达屏障的线程)从m_cond.wait(lock).

  • m_cond.wait(lock)现在,等待线程可能会因为其他原因而被唤醒。这就是m_generation进来的地方:如果它被改变了,那么屏障已经被重置并且线程可以继续。如果m_generation仍然包含相同的值,则线程需要返回到m_cond.wait(lock).

内部有一个自动变量wait()不会实现这一点,因为每个线程都有自己的实例。

于 2014-10-04T08:07:14.313 回答