huweide

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  15 随笔 :: 0 文章 :: 0 评论 :: 1473 阅读

一、使用场景

  在主线程中创建一个子线程去计数,计数累计100次后认为成功,并告诉主线程;主线程收到计数100次完成的信息后继续往下执行

二、条件变量的成员函数

wait:当前线程调用 wait() 后将被阻塞,直到另一个线程调用 noteify() 唤醒当前线程,使其被阻塞在锁竞争上的线程继续运行。

①void wait(unique_lock<mutex>& _Lck)();

②template <class _Predicate>

void wait(unique_lock<mutex>& _Lck, _Predicate _Pred) ;

_Pred : wait 的预测条件,

只有当 _Pred 为 false 且获取锁后调用 wait() 才会阻塞当前线程;

只有当 _Pred 为 true 且获取锁后 收到唤醒通知后 才会解除阻塞;

 

wait_for:可以指定一个时间段,在当前线程收到唤醒通知或指定的时间超时之前,该线程都会处于阻塞状态;超时或收到线程通知后返回

enum class cv_status { 
no_timeout,
timeout };

①cv_status wait_for(unique_lock<mutex>& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time) ;

②template <class _Rep, class _Period, class _Predicate>
bool wait_for(unique_lock<mutex>& _Lck, const chrono::duration<_Rep, _Period>& _Rel_time, _Predicate _Pred);

_Rel_time:等待的时间段,_Pred : wait_for的预测条件

当 _Pred 为 true   时,立刻唤醒线程,返回 true(_Pred 的状态),无需等待超时时间; 

当 _Pred 为 false 时,超过指定时间段未收到 notify_one 信号,唤醒线程,返回 false

定时间段内收到 notify_one 信号时,取决于_Pred 的状态,若为 _Pred 为 false,线程依然阻塞,返回 false(_Pred 的状态)

三、使用方法

复制代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

int main()
{
  /************************可以作为 While 的条件**************************/
  int i = 0;
  bool while_Out = false;
  std::mutex while_mtx;
  std::condition_variable while_cv;
  std::unique_lock<std::mutex>guard(while_mtx);
  while (while_cv.wait_for(guard, std::chrono::milliseconds(10), [&] {return while_Out == true; }) == false)
  {//当 while_Out 为 false 时,等待 10ms,返回 false,进入 while 循环
    if (i == 50)
    {
        while_Out = true;//当 while_Out 为 true 时,下次进行 wait_for 时无需等待超时时间,立刻返回 true ,结束循环
        while_cv.notify_one();//因为是同步,所以 notify_one 没有作用,要先走完 while
    }
    i++;
    std::cout << i << std::endl;//所以会输出51
  }
  std::cout << "test finish" << std::endl;
  /************************可以作为 While 的条件**************************/
  return 0;
}

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
#include <ctime>
#include <thread>
#include <iomanip>
 
void Get_time()
{
    std::time_t newTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
    auto formatTime = std::put_time(std::localtime(&newTime), "%Y-%m-%d %X");
    std::cout << "current time= " << formatTime << std::endl;
}
 
bool g_Out = false;
std::mutex g_mtx;
std::condition_variable g_cv;
 
void test()
{
    int i = 0;
    while (true)
    {
        i++;
        if (i == 50)
        {
            Get_time();
            g_Out = true;
            g_cv.notify_one();
            std::cout << " 唤醒主线程" << std::endl;
        }
    }
}
 
int main()
{
    g_Out = false;//阻塞主线程
    std::thread t1(test);
    t1.detach();
    std::unique_lock<std::mutex>guard(g_mtx);
    Get_time();
    std::cout << " 阻塞主线程" << std::endl;
    int ret = g_cv.wait_for(guard, std::chrono::minutes(1), [&] {return g_Out == true; });
    std::cout << ret << std::endl;
    //当 _Pred == false 时,在指定时间段(1分钟)内进入阻塞状态,
    //如果一直未接收到 notify_one 信号则超时唤醒线程,返回 _Pred 值
    //如果中途接收到 notify_one 信号:
    //①_Pred == true 则唤醒线程,返回 true;
    //②_Pred == false 则依然阻塞线程,直至超时返回 _Pred 值;
    return 0;
}

  

 

  

  

posted on   奇怪的菜鸟  阅读(304)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示