#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
using namespace std;
class Foo
{
public:
Foo() :flag_(0), thread1_(bind(&Foo::threadFunc1, this)), thread2_(bind(&Foo::threadFunc2, this))
{
}
~Foo()
{
thread1_.join();
thread2_.join();
}
protected:
private:
void threadFunc1()//如果我们在线程间共享数据,经常会存在一个线程等待另外一个线程的情况,它们之间存在先后关系。这个与互斥量不同,互斥量是保证多个线程的时候当前只有一个线程访问加锁的代码块,它们之间是不存在先后关系的。
{
unique_lock<mutex> ul(mutex_);//由于同时有两个线程需要操作flag变量,所以在读写的时候要加锁,std::unique_lock<std::mutex>会保证构造的时候加锁,离开作用域调用析构的时候解锁,所以不用担心加解锁不匹配。
while (flag_==0)//线程1需要等到线程2将flag设置为非0才进行打印
{//while (0 == flag_),必须这样写不能写成if(0 == flag_),因为在多核CPU下会存在虚假唤醒(spurious wakes)的情况。
cond_.wait(ul);//条件变量在wait的时候会释放锁的,所以其他线程可以继续执行。
}
cout << flag_ << endl;
}
void threadFunc2()//虽然线程1明显比线程2快些(人为制造等待3秒),但是线程1还是会等待线程2将flag设置为非0后才进行打印的。
{
this_thread::sleep_for((chrono::milliseconds(3000)));//为了测试,等待3秒
unique_lock<mutex> u1(mutex_);
flag_ = 100;
cond_.notify_one();
}
int flag_;
mutex mutex_;//mutex和cond必须在thread的前面。原因是:如果线程的定义在前面,线程初始化完成之后立马会执行线程函数,而线程函数里用到了mutex和cond,此时如果mutex和cond还没初始化完成,就会出现内存错误。
condition_variable cond_;
thread thread1_;
thread thread2_;
};
int main(int argc, char* argv[])
{
Foo f;
system("pause");
return 0;
}
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
using namespace std;
class Foo
{
public:
Foo() :flag_(0), thread1_(bind(&Foo::threadFunc1, this)), thread2_(bind(&Foo::threadFunc2, this))
{
}
~Foo()
{
thread1_.join();
thread2_.join();
}
protected:
private:
void threadFunc1()//如果我们在线程间共享数据,经常会存在一个线程等待另外一个线程的情况,它们之间存在先后关系。这个与互斥量不同,互斥量是保证多个线程的时候当前只有一个线程访问加锁的代码块,它们之间是不存在先后关系的。
{
unique_lock<mutex> ul(mutex_);//由于同时有两个线程需要操作flag变量,所以在读写的时候要加锁,std::unique_lock<std::mutex>会保证构造的时候加锁,离开作用域调用析构的时候解锁,所以不用担心加解锁不匹配。
while (flag_==0)//线程1需要等到线程2将flag设置为非0才进行打印
{//while (0 == flag_),必须这样写不能写成if(0 == flag_),因为在多核CPU下会存在虚假唤醒(spurious wakes)的情况。
cond_.wait(ul);//条件变量在wait的时候会释放锁的,所以其他线程可以继续执行。
}
cout << flag_ << endl;
}
void threadFunc2()//虽然线程1明显比线程2快些(人为制造等待3秒),但是线程1还是会等待线程2将flag设置为非0后才进行打印的。
{
this_thread::sleep_for((chrono::milliseconds(3000)));//为了测试,等待3秒
unique_lock<mutex> u1(mutex_);
flag_ = 100;
cond_.notify_one();
}
int flag_;
mutex mutex_;//mutex和cond必须在thread的前面。原因是:如果线程的定义在前面,线程初始化完成之后立马会执行线程函数,而线程函数里用到了mutex和cond,此时如果mutex和cond还没初始化完成,就会出现内存错误。
condition_variable cond_;
thread thread1_;
thread thread2_;
};
int main(int argc, char* argv[])
{
Foo f;
system("pause");
return 0;
}