为什么Boost库在实现线程屏障时会使用m_generation变量? [英] Why does the Boost library use an m_generation variable in its implementation of a thread barrier?

查看:99
本文介绍了为什么Boost库在实现线程屏障时会使用m_generation变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The boost library (before the C++11 standard), offered support for threads. As part of its support, it also offers the implementation of a "barrier", a simple class which allows synchronization. To quote the boost website:

屏障是一个简单的概念.也称为集合点,它是多个线程之间的同步点.屏障针对特定数量的线程(n)配置,并且当线程到达屏障时,它们必须等待直到所有n个线程都到达了.第n个线程到达屏障后,所有等待的线程都可以继续执行,并且屏障被重置."

"A barrier is a simple concept. Also known as a rendezvous, it is a synchronization point between multiple threads. The barrier is configured for a particular number of threads (n), and as threads reach the barrier they must wait until all n threads have arrived. Once the n-th thread has reached the barrier, all the waiting threads can proceed, and the barrier is reset."

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

The implementation of the main function of the barrier (wait), as of Boost 1.54, is shown below:

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;
}

可以看出,该屏障是可重复使用的:屏障一旦建造,在首次使用后无需销毁.

It can be seen that the barrier is reusable: Once constructed, it doesn't need to be destroyed after its first use.

我现在的问题是:m_generation的作用是什么?我假设boost库的作者有理由将其包括在内.每次重置/准备重用障碍时,它都会增加,但是到什么目的呢?它是一个私有变量,因此无法从外部读取.只需在wait()函数中使用一个简单的内部bool变量即可解决相同的问题,而无需使用私有类变量.

My question now is: What is the variable m_generation for? I am assuming the writers of the boost library had a reason to include it. It is incremented each time the barrier is reset/ready to be reused, but to what end? It is a private variable, thus it cannot be read out from the outside. The same problem could just as easily be solved with a simple internal bool variable inside the wait() function, without having a private class variable.

推荐答案

总而言之,需要 m_ge​​neration 来处理

In a nutshell, m_generation is needed to deal with spurious wakeups.

生成计数器与条件变量一起使用,向等待屏障的所有线程发信号通知它们可以自由进行:

The generation counter is used in conjunction with the condition variable to signal to all threads waiting on the barrier that they are free to proceed:

  • 一旦有 m_threshold 个线程到达了障碍,其生成编号就会增加,并发出条件变量信号.这会导致等待线程(即那些较早到达屏障的线程)从 m_cond.wait(lock)唤醒.

  • Once there are m_threshold threads that have reached the barrier, its generation number gets bumped up, and the condition variable is signalled. This causes the waiting threads (i.e. those that have reached the barrier earlier) to wake up from m_cond.wait(lock).

现在,等待线程可以从 m_cond.wait(lock)唤醒,用于其他原因.这是 m_ge​​neration 出现的地方:如果更改了该代码,则说明屏障已重置,线程可以继续进行.如果 m_ge​​neration 仍包含相同的值,则线程需要返回到 m_cond.wait(lock).

Now, the waiting threads can wake up from m_cond.wait(lock) for other reasons. This is where m_generation comes in: if it's changed, then the barrier has been reset and the thread can proceed. If m_generation still contains the same value, the thread needs to go back into m_cond.wait(lock).

wait()中具有自动变量将无法实现这一目标,因为每个线程都有自己的实例.

Having an automatic variable inside wait() would not achieve this, since each thread would have its own instance.

这篇关于为什么Boost库在实现线程屏障时会使用m_generation变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆