多线程Condition_variable和unique_lock用法

condition_variable是C++标准程序库中的一个头文件,定义了C++11标准中的一些表示线程的类、用于互斥访问的类与方法等。

一,成员函数:

1,Wait functions

wait
    Wait until notified (public member function)
wait_for
    Wait for timeout or until notified (public member function)
wait_until
    Wait until notified or time point (public member function)

2,Notify functions

notify_one
    Notify one (public member function)
notify_all
    Notify all (public member function)

二,wait的两种用法:

1,只有一个lock形参

void wait( std::unique_lockstd::mutex& lock );

2,一个lock形参,一个lambda表达式,或者一个函数。

void wait( std::unique_lockstd::mutex& lock, Predicate pred );

三,唤醒方式:

两种wait都需要notify_one或者notify_all唤醒,但是第二种即使唤醒也满足表达式的条件,即:要返回true。
其中第二种wait的表达式至少要执行两次。
第一次是程序跑到wait时,第二次是收到notify时。

四,引申

wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。当前线程会一直被阻塞,进入WAITTING状态。
但是此时的unique_lock和单独用unique_lock时区别还是挺大的。
单独使用unique_lock时,其他的线程要等待当前线程unlock。
配合wait时,只有执行表达式时才会触发mutex的lock,执行结束或者没有执行时,都处于unlock状态。

五,例子

#include <stdio.h>
#include <stdlib.h>
#include <mutex>

#include <chrono>    // std::chrono::seconds
#include <iostream>  // std::cout
#include <thread>    // std::thread, std::this_thread::sleep_for
#include <condition_variable>


std::condition_variable cv;
std::mutex my_lock;
std::mutex g_lock;
int g_variable = 0; 

void thread_task2() 
{

    std::cout << "thread_task2 step1"<< std::endl;
    g_lock.lock();
    
    std::cout << "thread_task2 step2"<< std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    std::cout << "thread_task2 step3"<< std::endl;
    std::lock_guard<std::mutex> lock(my_lock);  
    std::cout << "thread_task2 step4"<< std::endl;

    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "thread_task2 step5"<< std::endl;
    
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "thread_task2 step6 "<< std::endl;
    if(g_variable == 5)
    {
        std::cout << "thread_task2 step7 "<< std::endl;
        g_variable = 100;
        std::cout << "thread_task2 step8 "<< std::endl;
        cv.notify_one();
    }
    g_lock.unlock();
}

bool istrue()
{
    std::cout << "istrue step1"<< std::endl;
    g_lock.lock();
    std::cout << "istrue step2"<< std::endl;
    g_lock.unlock();
    std::cout << "istrue step3"<< std::endl;
    return (g_variable == 100);
}

void thread_task3() 
{
    std::cout << "thread_task3 step1"<< std::endl;
    g_variable = 5;
    std::this_thread::sleep_for(std::chrono::seconds(2));
    
    std::unique_lock<std::mutex> lck(my_lock);
    std::this_thread::sleep_for(std::chrono::seconds(5));
    cv.wait(lck,istrue);
    std::cout << "thread_task3 step2"<< std::endl;
}

int main(int argc, const char *argv[])
{
    std::thread thread2 = std::thread(thread_task2);
    std::thread thread3 = std::thread(thread_task3);

    thread2.join();
    thread3.join();
    
    return EXIT_SUCCESS;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值