当前位置: 首页 > article >正文

高阶开发基础——快速入门C++并发编程5 信号量的使用

目录

简单说说condition_variable

一个例子


简单说说condition_variable

condition_varaible是mutex的一个更加高阶的使用。它用来负责简化资源的请求和使用。或者说,他让多个线程对资源的使用变得有序。

一个代表性的例子就是我们的消费生产模型。假设有两个线程,一个线程负责生产数据,另一个线程负责消费数据。生产线程需要等到消费线程处理完数据后才能继续生产,而消费线程需要等到有数据时才能开始消费。

这时候就可以用 condition_variable 来实现:

  1. 等待条件:消费线程发现没有数据时,会调用 condition_variablewait() 函数进入等待状态,直到生产线程通知它有数据了。

  2. 通知条件:生产线程生产完数据后,调用 condition_variablenotify_one()notify_all() 函数,告诉消费线程“数据准备好了,可以开始消费了”。

简单来说,condition_variable 就像是一个信号灯:

  • 线程可以在这个信号灯前等待(wait()),直到其他线程发出信号(notify())。

  • 当信号发出后,等待的线程就会被唤醒,继续执行。

它的核心作用是避免线程忙等待(不断检查条件是否成立),从而节省 CPU 资源。

一个例子

我们就对上面的例子进行编程

#include <chrono>
#include <condition_variable>
#include <mutex>
#include <print>
#include <queue>
#include <thread>
std::mutex mtx;
std::queue<int> global_working_queue;
std::condition_variable global_con_var;
​
bool shell_stop = false;
void producer() {
    for (int i = 0; i < 50; i++) {
        {
            std::unique_lock<std::mutex> locker(mtx);
            global_working_queue.push(i);
            global_con_var.notify_one();
            std::print("we push {} into the task\n", i);
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    shell_stop = true;
}
​
void consumer() {
    while (!shell_stop) {
        std::unique_lock<std::mutex> locker(mtx);
        // if the queue is empty, we need to wait
        global_con_var.wait(locker, [](){return !global_working_queue.empty() || !shell_stop;});
        if(global_working_queue.empty()){
            continue;
        }
        
        int value = global_working_queue.front();
        global_working_queue.pop();
        std::print("Fetch the value in consumer {}\n", value);
    }
}
​
int main() {
    auto pro = std::thread(producer);
    auto con = std::thread(consumer);
​
    pro.join();
    con.join();
}

在这个例子中,笔者让一个消费者源源不断的往里塞入数据。每当我们塞好了数据,就会通知我们的线程取出数据。进行消费。对于生产者,则是每一次准备处理数据的时候,先向条件变量请示一下,我可不可以进行处理。条件变量依据我们的判断条件,当我们的输入不是队列空的时候,就不需要等待,直接处理队列内数据(wait的判断条件要求的是当为真的适合不去等待,假的时候(也就是资源此时不可以被请求,你要等待)的时候休眠,直到消费者线程提醒你你要起来处理数据)


http://www.kler.cn/a/531946.html

相关文章:

  • git 项目的更新
  • 尚硅谷课程【笔记】——大数据之Shell【一】
  • Linux基础 ——tmux vim 以及基本的shell语法
  • Vue3 完整学习笔记 - 第四部分
  • AI智慧社区--Excel表的导入导出
  • 700. 二叉搜索树中的搜索
  • 自定义数据集 使用paddlepaddle框架实现逻辑回归
  • 农历2025开始 笔记
  • 基于STM32的智能健康监测手环
  • Sqoop导入MySQL中含有回车换行符的数据
  • 【Deep Seek本地化部署】修改模型保存位置
  • (done) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)
  • 【C++】继承(下)
  • 吴恩达深度学习——卷积神经网络基础
  • GESP2023年12月认证C++六级( 第三部分编程题(1)闯关游戏)
  • PyQt4学习笔记1】使用QWidget创建窗口
  • Kubernetes服务网格实战:从理论到落地
  • 经典本地影音播放器MPC-BE.
  • 动手学深度学习-3.1线性回归 问题汇总
  • 指导初学者使用Anaconda运行GitHub上One - DM项目的步骤
  • Python玄学
  • 【Jax和Flax介绍】
  • redis实际开发应用简单实现
  • c语言练习题【数据类型、递归、双向链表快速排序】
  • 14-9-3C++STL的set容器
  • C语言按位取反【~】详解,含原码反码补码的0基础讲解【原码反码补码严格意义上来说属于计算机组成原理的范畴,不过这也是学好编程初级阶段的必修课】