问题描述
有多个正在运行的线程,我需要确保在继续操作之前,我的每个线程都达到了某个特定点.我需要设置一种障碍.考虑可以从多个线程运行的函数func
:
Having several threads running I need to guaranty that every of my threads reached a certain point before proceeding. I need to implement a kind of barrier. Consider a function func
which can be run from several threads:
void func()
{
operation1();
// wait till all threads reached this point
operation2();
}
使用C ++ 11和VS12实现此障碍的最佳方法是什么,如果需要的话,可以考虑提高.
What is best way to realise this barrier using C++ 11 and VS12, considering boost if needed.
推荐答案
您可以使用 boost :: barrier
不幸的是,线程屏障概念本身并不是c ++ 11或Visual c ++的一部分.
在纯c ++ 11中,您可以使用条件变量和一个计数器.
You could use boost::barrier
Unfortunately, the thread barrier concept itself is not part of c++11 or visual c++.
In pure c++11 you could use a condition variable and a counter.
#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();
}
每个线程等待直到满足谓词.最后一个线程将使谓词有效,并允许等待的线程继续进行.如果要重用障碍(例如多次调用函数),您需要另一个变量以重置计数器.
Each thread wait till a predicate is met. The last thread will make the predicate valid, and allow the waiting threads to proceed. If you want to reusethe barrier (for instance call the function multiple times), you need anothervariable to reset the counter.
当前的实现方式是有限的.两次调用func();func();
可能不会使线程第二次等待.
This current implementation is limited. A calling func();func();
twice may not make threads wait the second time.
这篇关于实现线程之间的同步屏障的最佳方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!