c++11の条件变量

 

一、条件变量的引入

std::condition_variable 解决了死锁并且控制的资源的访问顺序二避免不必要的等待。当互斥操作不够用而引入的。比如,线程可能需要等待某个条件为真才能继续执行,而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。所以,condition_variable实例被创建出现主要就是用于唤醒等待线程从而避免死锁。std::condition_variable的 notify_one()用于唤醒一个线程;notify_all() 则是通知所有线程。

二、下面是一个引用的例子

假设想实现一个简单的消费者生产者模型,一个线程往队列中放入数据,一个线程往队列中取数据,取数据前需要判断一下队列中确实有数据,由于这个队列是线程间共享的,所以,需要使用互斥锁进行保护,一个线程在往队列添加数据的时候,另一个线程不能取,反之亦然。

一般的:

复制代码

std::deque<int> q;
std::mutex mu;

void function_1() {
    int count = 10;
    while (count > 0) {
        std::unique_lock<std::mutex> locker(mu);
        q.push_front(count);
        std::cout << "t1 put a value : " << count << std::endl;
        locker.unlock();
        std::this_thread::sleep_for(std::chrono::seconds(1));
        count--;
    }
}

void function_2() {
    int data = 0;
    while (data != 1) {
        std::unique_lock<std::mutex> locker(mu);
        if (!q.empty()) {
            data = q.back();
            q.pop_back();
            locker.unlock();
            std::cout << "t2 got a value from t1: " << data << std::endl;
        }
        else {
            locker.unlock();
        }
    }
}
int main() {
    std::thread t1(function_1);
    std::thread t2(function_2);
    t1.join();
    t2.join();
    return 0;
}

复制代码

std::this_thread::sleep_for(std::chrono::seconds(1));表示延时1s,所以这个生产的过程是很慢的;function_2函数是消费者,存在着一个while循环,只有在接收到表示结束的数据的时候,才会停止,每次循环内部,都是先加锁,判断队列不空,然后就取出一个数,最后解锁。所以说,在1s内,做了很多无用功!这样的话,单核CPU占用率会很高,可能达到100%。

复制代码

// threadTest.cpp: 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <fstream>
#include <deque>
#include <condition_variable>

using namespace std;


std::deque<int> q;
std::mutex mu;
std::condition_variable cond;

void function_1() 
{
    int count = 10;
    while (count>0)
    {
        std::unique_lock<mutex> locker(mu);
        q.push_back(count);
        locker.unlock();
        cond.notify_all();
        std::this_thread::sleep_for(chrono::seconds(1));
        count--;
    }

}

void funciton_2() 
{
    int data = 0;
    while (data != 1)
    {
        std::unique_lock<mutex> locker(mu);
        cond.wait(locker, [](){return !q.empty(); }); //  while(q.empty()) {cond.wait(locker); }// Unlock mu and wait to be notified 等同写法
        data = q.back(); 
        q.pop_back(); 
        locker.unlock(); 
        cout << "t2 get a value form t1 " << data << endl; } 
    } 

int main() { 
thread t1(function_1); 
thread t2(funciton_2); 
t1.join(); 
t2.join();
std::getchar(); 

return 0; }

复制代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值