线程间同步,条件变量

#include
#include
#include
#include
#include
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 ul(mutex_);//由于同时有两个线程需要操作flag变量,所以在读写的时候要加锁,std::unique_lock会保证构造的时候加锁,离开作用域调用析构的时候解锁,所以不用担心加解锁不匹配。
        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 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;
}

你可能感兴趣的:(线程间同步,条件变量)