实现线程之间同步屏障的最佳方法是什么

新手上路,请多包涵

在运行多个线程时,我需要保证我的每个线程在继续之前都达到了某个点。我需要实施一种障碍。考虑一个函数 func 可以从多个线程运行:

 void func()
{
  operation1();
  // wait till all threads reached this point
  operation2();
}

什么是使用 C++ 11 和 VS12 实现这个障碍的最佳方法,如果需要,考虑提升。

原文由 GregPhil 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 656
1 个回答

你可以使用 boost::barrier

不幸的是,线程屏障概念本身并不是 c++11 或 Visual c++ 的一部分。

在纯 c++11 中,您可以使用 条件变量 和计数器。

 #include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>

class my_barrier
{

 public:
    my_barrier(int count)
     : thread_count(count)
     , counter(0)
     , waiting(0)
    {}

    void wait()
    {
        //fence mechanism
        std::unique_lock<std::mutex> lk(m);
        ++counter;
        ++waiting;
        cv.wait(lk, [&]{return counter >= thread_count;});
        cv.notify_one();
        --waiting;
        if(waiting == 0)
        {
           //reset barrier
           counter = 0;
        }
        lk.unlock();
    }

 private:
      std::mutex m;
      std::condition_variable cv;
      int counter;
      int waiting;
      int thread_count;
};

int thread_waiting = 3;
my_barrier barrier(3);

void func1()
{
    std::this_thread::sleep_for(std::chrono::seconds(3));
    barrier.wait();
    std::cout << "I have awakened" << std::endl;
}

void func2()
{
    barrier.wait();
    std::cout << "He has awakened!!" << std::endl;
}

int main() {
    std::thread t1(func1);
    std::thread t2(func2);
    std::thread t3(func2);
    t1.join();
    t2.join();
    t3.join();
}

每个线程等待直到满足谓词。最后一个线程将使谓词有效,并允许等待的线程继续。如果要重用屏障(例如多次调用该函数),则需要另一个变量来重置计数器。

当前的实现是有限的。调用 func();func(); 两次可能不会使线程第二次等待。

原文由 UmNyobe 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题