【Linux】多线程_5

文章目录

  • 九、多线程
    • 6. 条件变量
    • 7. 生产者消费者模型
  • 未完待续


九、多线程

6. 条件变量

在多线程编程中,一个或多个线程可能需要等待某个条件的发生,然后才能继续执行,而不是一直忙等。这种等待通常会占用CPU资源。条件变量提供了一种机制,使得线程可以等待某个条件的发生,同时释放CPU资源给其他线程使用。当一个线程需要等待某个条件时,它会先获取互斥锁,然后调用条件变量的等待函数,此时互斥锁会被释放,线程 进入等待队列 。当条件发生时,另一个线程会获取互斥锁,然后调用条件变量的 通知 函数,通知等待的线程条件已经满足。总而言之,条件变量就是一种 等待队列 + 通知唤醒 的机制。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里条件变量的使用方法和互斥锁几乎一样,这里不再描述。
我们来简单使用一下条件变量:
Makefile

testCond:testCond.ccg++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f testCond

testCond.cc

#include <iostream>
#include <string>
#include <pthread.h>
#include <vector>
#include <unistd.h>
using namespace std;// 全局的条件变量
pthread_cond_t gcond = PTHREAD_COND_INITIALIZER;
// 全局的互斥锁
pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;void* MasterCore(void* args)
{sleep(3);cout << "Master 线程开始工作了" << endl;string name = (const char*)args;while (true){// 唤醒等待队列头部的线程pthread_cond_signal(&gcond);cout << "Masther 线程唤醒了一个线程" << endl;// 唤醒所有线程//pthread_cond_broadcast(&gcond);//cout << "Master 线程广播了一个信号, 唤醒了所有线程" << endl;sleep(1);}
}void* SlaverCore(void* args)
{string name = (const char*)args;while (true){// 加锁pthread_mutex_lock(&gmutex);// 等待条件变量pthread_cond_wait(&gcond, &gmutex);// 解锁pthread_mutex_unlock(&gmutex);cout << "当前被叫醒的线程是: " << name << endl;}
}void StartMaster(vector<pthread_t>* tidsptr)   
{pthread_t tid;int n = pthread_create(&tid, nullptr, MasterCore, (void*)"Master Thread");if (n == 0){cout << "Master Thread Created" << endl;}tidsptr->emplace_back(tid);
}void StartSlaver(vector<pthread_t>* tidsptr, int threadnum = 3)
{for (int i = 0; i < threadnum; i++){char* name = new char[64];snprintf(name, 64, "Slaver-%d", i + 1);pthread_t tid;int n = pthread_create(&tid, nullptr, SlaverCore, name);if (n == 0){cout << "Slaver Thread " << name << " Created" << endl;tidsptr->emplace_back(tid);}}
}void WaitThread(vector<pthread_t>& tids)
{for (auto& tid : tids){pthread_join(tid, nullptr);}
}int main()
{vector<pthread_t> tids;StartMaster(&tids);StartSlaver(&tids, 5);WaitThread(tids);return 0;
}

在这里插入图片描述

7. 生产者消费者模型

生产者消费者模型是一种常见的并发编程模型,用于解决多个线程之间的协作问题。在生产者消费者模型中,有三种关系:①生产者和生产者之间的互斥关系。②消费者和消费者之间的互斥关系。③生产者和消费者之间的互斥且同步的关系有两种角色:①负责生产数据的生产者。②负责消费数据的消费者有一个交易场所:①提供数据交易的可以短暂存储数据的内存——数据结构对象
在这里插入图片描述

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。
在这里插入图片描述


未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/871765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 的四大引用详解】

首先分别介绍一下这几种引用 强引用&#xff1a; 只要能通过GC ROOT根对象引用链找到就不会被垃圾回收器回收&#xff0c;当所有的GC Root都不通过强引用引用该对象时&#xff0c;才能被垃圾回收器回收。 软引用&#xff08;SoftReference&#xff09;&#xff1a; 当只有软引…

从汇编层看64位程序运行——栈上变量的rbp表达

在《从汇编层看64位程序运行——参数传递的底层实现》中&#xff0c;我们看到了栈帧中的变量是分为两种&#xff1a; 局部非静态变量。调用超过6个参数的函数时&#xff0c;从第7个参数开始的入参。 比如下面的代码 void foo10(int a, int b, int c, int d, int e, int f, i…

数仓工具—Hive基础之临时表及示例

Hive基础之临时表及示例 临时表是应用程序自动管理在大型或复杂查询执行期间生成的中间数据的一种便捷方式。Hive 0.14 及更高版本支持临时表。可以在用户会话中像使用普通表一样多次使用它们。在本文中,我们将介绍 Apache Hive 临时表,以及如何创建和使用限制的示例。 Hiv…

Python实现简单的ui界面设计(小白入门)

引言&#xff1a; 当我们书写一个python程序时&#xff0c;我们在控制台输入信息时&#xff0c;往往多有不便&#xff0c;并且为了更加美观且直观的方式输入控制命令&#xff0c;我们常常设计一个ui界面&#xff0c;这样就能方便执行相关功能。如计算器、日历等界面。 正文&a…

水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集)

水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 目录 水表数字识别2&#xff1a;Pytorch DBNet实现水表数字检测(含训练代码和数据集) 1.前言 2. 水表数字识别的方法 3. 水表数字识别数据集 4. 水表数字分割模型训练 &#xff08;1&#x…

qt 销毁一个窗口的逻辑都有啥

在 Qt 中&#xff0c;销毁一个窗口通常涉及几个关键步骤。这些步骤确保窗口资源被正确释放&#xff0c;避免内存泄漏和其他潜在问题。以下是销毁一个 Qt 窗口时通常需要考虑的逻辑&#xff1a; 关闭窗口&#xff1a; 用户可以通过点击窗口的关闭按钮&#xff08;通常是右上角的…

hnust 1802: 二叉树遍历2

hnust 1802: 二叉树遍历2 题目描述 二叉树的前序、中序、后序遍历的定义&#xff1a; 前序遍历&#xff1a;对任一子树&#xff0c;先访问跟&#xff0c;然后遍历其左子树&#xff0c;最后遍历其右子树&#xff1b; 中序遍历&#xff1a;对任一子树&#xff0c;先遍历其左子树…

JavaSE 面向对象程序设计进阶 IO 压缩流 解压缩流

目录 解压缩流 压缩流 解压缩流 压缩包 压缩包里面的每一个文件在java中都是一个ZipEntry对象 把每一个ZipEntry按照层级拷贝到另一个文件夹当中 import java.io.*; import java.util.Date; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;public cl…

c#与欧姆龙PLC通信——如何更改PLC的IP地址

前言 我们有时候需要改变欧姆龙Plc的ip地址,下图有两种更改方式,一种是已知之前Plc设置的Ip地址,还有一种是之前不知道Pl的Ip地址是多少,下面分别做介绍。 1、已知PLC的IP地址的情况下更改地址 假设已知PLC的Ip地址,比如本文中PLC的IP为192.168.1.2,我首先将电脑的IP地…

17:低功耗篇(PWR)---HAL库

一:PWR 1:简历 PWR&#xff08;Power Control&#xff09;电源控制 PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上升到…

51单片机9(使用左移实现流水灯编程)

一、序言&#xff1a;下面我们来给大家介绍一下这个流水灯&#xff0c;流水灯如何来实现&#xff1f;我们依然使用这个工程来完成它。 1、那要使用实现这个流水灯&#xff0c;那我们只需要让D1到D8逐个的点亮&#xff0c;那同样要实现它足够的点亮&#xff0c;也会涉及到延时&…

使用requirements.txt文件安装cuda(GPU)版本的pytorch

使用requirements.txt文件安装cuda&#xff08;GPU&#xff09;版本的pytorch 问题描述解决方法 问题描述 使用requirements.txt可以轻松地帮助我们配置新环境&#xff0c;然而&#xff0c;当使用requirements.txt安装pytorch时有时会出现仅能安装cpu版本pytorch的情况。 举例…

从汇编层看64位程序运行——函数的调用和栈平衡

函数调用 不知道有没有人想过一个问题&#xff1a;A函数调用B函数&#xff0c;B函数是如何知道在调用结束后回到A函数中的&#xff1f; 比如下面的代码&#xff0c;main函数调用foo。当foo执行完毕&#xff0c;需要执行main函数的return 0语句。但是main和foo是割裂的&#x…

SVN 分支管理深入解析

SVN 分支管理深入解析 引言 在软件开发过程中,版本控制是一个核心环节,它帮助团队有效地管理代码变更,协作开发,并维护项目历史。SVN(Subversion)作为一种流行的版本控制系统,提供了分支(Branch)功能,允许开发者在独立的线路上进行工作,而不会影响到主代码库。本文…

探索编程的多维宇宙:LangChain支持的编程范式全解析

探索编程的多维宇宙&#xff1a;LangChain支持的编程范式全解析 引言 在软件开发的丰富生态系统中&#xff0c;不同的编程范式为解决特定问题提供了独特的方法和工具。LangChain&#xff0c;作为一个多语言编程工具链&#xff0c;其设计理念在于支持多种编程范式&#xff0c;…

JavaWeb---HTML

一 HTML入门 1.1 HTML&CSS&JavaScript的作用 HTML 主要用于网页主体结构的搭建 CSS 主要用于页面元素美化 JavaScript 主要用于页面元素的动态处理 1.2 什么是HTML HTML是Hyper Text Markup Language的缩写。意思是超文本标记语言。它的作用是搭建网页结构&#xff0c…

.NET在工控上位机开发中有哪些成功的案例?

简述 工业自动化的浪潮正推动着传统制造业向智能化转型。在这一进程中&#xff0c;.NET技术以其强大的功能和灵活性&#xff0c;成为工控上位机开发的有力工具。本文将带您探索那些成功运用.NET技术的工控项目&#xff0c;展现.NET在工控领域的卓越优势。 工控领域的.NET革新 工…

Vulnhub靶场DC-3-2练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. joomla漏洞查找2. SQL注入漏洞3. 破解hash4. 上传一句话木马5. 蚁剑连接shell6. 反弹shell7. 提权 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-3-2.zip 介绍&#…

一文清晰了解CSS——简单实例

首先一个小技巧&#xff1a; 一定要学会的vsCode格式化整理代码的快捷键&#xff0c;再也不用手动调格式了-腾讯云开发者社区-腾讯云 (tencent.com) CSS选择器用于选择要应用样式的HTML元素。常见的选择器包括&#xff1a; 类选择器&#xff1a;以.开头&#xff0c;用于选择具…

React Element介绍

React Element是React中的核心概念之一&#xff0c;它代表了React应用中的UI元素。React Element并不是真实的DOM节点&#xff0c;而是一个轻量级的、不可变的、描述性的对象&#xff0c;它包含了创建UI所需的类型&#xff08;type&#xff09;、属性&#xff08;props&#xf…