1.1条件变量

(1)当⼀个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。
(2)例如⼀个线程访问队列时,发现队列为空,它只能等待,只到其它线程将⼀个节点添加到队列
中。这种情况就需要⽤到条件变量。
  1.2同步概念与竞态条件
(1)同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避饥饿问题
(2)竞态条件:竞态条件是并发编程中常见的问题,指多个线程或进程对共享资源的访问顺序不确定,导致程序行为不可预测或错误
竞态条件的常见情况有:
(1)检查后行动:对于main线程,如果文件a不存在,则创建文件a,但是在判断文件a不存在之后,Task线程创建了文件a,这时候先前的判断结果已经失效,(main线程的执行依赖了一个错误的判断结果)此时文件a已经存在了,但是main线程还是会继续创建文件a,导致Task线程创建的文件a被覆盖、文件中的内容丢失等等问题
(2)非原子操作的++,--等操作:在这些非原子操作时会分成三步,内存先将数据搬到cpu,cpu计算,再将数据搬回内存,其中每一个步骤线程都可能被切换并且修改数据,导致该数据的更新丢失
(3)延迟初始化:在单例模式中,如果没有适当的同步机制,可能导致多个线程同时创建实例
1.3条件变量函数
初始化
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t
*restrict attr);
参数:
cond:要初始化的条件变量
attrNULL
销毁
int pthread_cond_destroy(pthread_cond_t *cond)
等待条件满⾜
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict
mutex);
参数:
cond:要在这个条件变量上等待
mutex:互斥量,等待期间解锁,唤醒时再次加锁
唤醒等待
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);

  1.4 生产者消费者模型

  ⽣产者消费者模式就是通过⼀个容器来解决⽣产者和消费者的强耦合问题。⽣产者和消费者彼此之间不直接通讯,⽽通过阻塞队列来进⾏通讯,所以⽣产者⽣产完数据之后不⽤等待消费者处理,直接扔给阻塞队列,消费者不找⽣产者要数据,⽽是直接从阻塞队列⾥取,阻塞队列就相当于⼀个缓冲区,平衡了⽣产者和消费者的处理能⼒。这个阻塞队列就是⽤来给⽣产者和消费者解耦的。

  生产者消费者模型的优点:(1)解耦合 (2)支持并发 (3)支持忙先不均

  1.5基于BlockingQueue的⽣产者消费者模型

  BlockingQueue:在多线程编程中阻塞队列(Blocking Queue)是⼀种常⽤于实现⽣产者和消费者模型的数据结构。其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放⼊了元素;当队列满时,往队列⾥存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)

简单示例:

  这里封装了一个BlockQue类,成员变量说明:定义了最大容量,一个互斥锁,生产者与消费者应该是互斥的,否则会导致数据错乱,设置了两个条件变量分别在队列为空和满的时候使线程进入等待,当队列有元素或不为空时由生产者或消费者线程根据wait_nums来决定是否唤醒对应的等待线程。成员函数说明:生产者与生产者之间,消费者与消费者是互斥的,所以在进入生产和消费的时候只允许一个线程进入,队列为空或满时都会进入等待,此时为了防止伪唤醒使用while循环来控制。(伪唤醒的情况:直接使用pthread_cond_broadcast唤醒所有的生产线程,但是此时只能有一个线程拿到锁,其他线程苏醒了但是还在等待锁,如果使用if判断满的话如果下一次锁还是被生产者拿到,此时队列还是满的,但是接拿到锁的线程还会继续插入发生错误,使用while就是为了在伪唤醒以后多加一次判断,如果条件没有达到继续进入条件等待。)

  1.6为什么 pthread_cond_wait 需要互斥量?

(1)条件等待是线程间同步的⼀种⼿段,如果只有⼀个线程,条件不满⾜,⼀直等下去都不会满⾜,所以必须要有⼀个线程通过某些操作,改变共享变量,使原先不满⾜的条件变得满⾜,并且友好的通知等待在条件变量上的线程。
(2)条件不会⽆缘⽆故的突然变得满⾜了,必然会牵扯到共享数据的变化。所以⼀定要⽤互斥锁来保护。没有互斥锁就⽆法安全的获取和修改共享数据。

  1.7条件变量的封装

2.POSIX信号量

  POSIX信号量和SystemV信号量作⽤相同,都是⽤于同步操作,达到⽆冲突的访问共享资源⽬的,但POSIX可以⽤于线程间同步。

初始化信号量
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
pshared:0表⽰线程间共享,⾮零表⽰进程间共享
value:信号量初始值
销毁信号量
int sem_destroy(sem_t *sem);
等待信号量
功能:等待信号量,会将信号量的值减1
int sem_wait(sem_t *sem); //P()
发布信号量
功能:发布信号量,表⽰资源使⽤完毕,可以归还资源了。将信号量值加1
int sem_post(sem_t *sem);//V()

2.2基于环形队列的⽣产消费模型

环形队列采⽤数组模拟,⽤模运算来模拟环状特性

环形队列的⽣产消费模型代码示例:

Sem封装

RingBuffer.hpp

  这里将Mutex和封装好的Sem都应用了,需要查看具体及测试代码的同学可以在我的gitee仓库下的RingBuffer文件夹获取,该项目单生产单消费以及多生产多消费都是支持的,生产与消费之间是并发的,相较于阻塞队列生产者消费者模型提高了效率。

我的gitee仓库https://gitee.com/toutie40/study_code.git

本文到此结束,感谢大家观看,希望对你有所帮助,有错误请多多指教。

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

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

相关文章

前端进阶指南:JavaScript性能优化实战全解析

深入剖析 JavaScript 性能瓶颈&#xff0c;分享优化技巧与最佳实践&#xff0c;让你的前端应用更快、更稳、更流畅。 &#x1f4d1; 目录 一、前言 二、性能瓶颈的常见来源 三、JavaScript代码优化技巧 1. 避免重复计算 2. 合理使用防抖与节流 3. 使用事件委托 四、渲染…

RabbitMQ:SpringAMQP Direct Exchange(直连型交换机)

目录一、案例需求二、基础配置三、代码实现直连型交换机也叫做定向交换机&#xff0c;通过RoutingKey绑定交换机与队列直接的关系。 生产者源码 消费者源码 一、案例需求 在RabbitMQ控制台中&#xff0c;声明队列direct.queue1和direct.queue2。在RabbitMQ控制台中&#xff…

implement libtime on Windows

因为Windows的time命令和Linux的time命令不一样&#xff0c;尝试实现libtime libtime.h /** libtime.h - 跨平台时间测量库* 功能&#xff1a;执行外部命令并测量其运行时间和资源使用*/#ifndef LIBTIME_H #define LIBTIME_H#include <stdio.h> #include <stdlib.h>…

Unity进阶--C#补充知识点--【C#各版本的新功能新语法】C#1~4与C#5

来源于唐老狮的视频教学&#xff0c;仅作记录和感悟记录&#xff0c;方便日后复习或者查找 一.C#版本与Unity的关系 1.各Unity版本支持的C#版本 更多信息可以在Untiy官网说明查看 https://docs.unity3d.com/2020.3/Documentation/Manual/CSharpCompiler.html&#xff08;这个好…

水闸安全综合监测系统解决方案

一、方案概述 水闸作为重要的水利工程设施&#xff0c;承担着防洪、排涝、供水和灌溉等关键功能。其安全性直接关系到下游人民群众的生命财产安全以及区域经济的稳定发展。近年来&#xff0c;随着极端天气频发和工程老化问题日益突出&#xff0c;水闸安全监测工作显得尤为重要。…

基于单片机智能点滴输液系统

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目速选一览表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品题目功能速览 概述 该系统基于单片机控制技术&#xff0c;结合传感器和无线通信模块&#xff0c;实现对输液过程的实…

AI数据仓库管理提升效率

内容概要在数字化转型浪潮中&#xff0c;AI数据仓库管理正重塑企业数据处理格局。本部分简要介绍其核心机制&#xff0c;即通过智能API接入外部数据源实现多平台数据无缝整合&#xff0c;随后应用数据清洗技术去除冗余信息&#xff0c;确保数据质量。同时&#xff0c;加密存储机…

使用 Docker 安装长安链管理平台 + 部署区块链与示例合约

文章目录简介登录官网GithubPodman 配置&#xff08;Docker 配置 registry 地址&#xff09;安装长安链管理平台下载源码docker-compose.yml登录管理平台部署区块链Dockerfile构建镜像部署长安链订阅区块链部署合约下载示例合约部署示例合约投票管理文件哈希存证查找存证信息区…

Python训练营打卡 DAY 41 简单CNN

知识回顾 数据增强卷积神经网络定义的写法batch归一化&#xff1a;调整一个批次的分布&#xff0c;常用与图像数据特征图&#xff1a;只有卷积操作输出的才叫特征图调度器&#xff1a;直接修改基础学习率 卷积操作常见流程如下&#xff1a; 1. 输入 → 卷积层 → Batch归一化层…

云端赋能,智慧运维:分布式光伏电站一体化监控平台研究

摘要 本文针对分布式光伏电站存在的监管困难、火灾隐患、系统繁杂及运维不规范等行业痛点&#xff0c;提出AcrelCloud-1200光伏运维云平台解决方案。平台通过ANet-1E2S-4G网关集成多品牌逆变器数据&#xff0c;结合视频监控与气象站&#xff0c;实现电站全域监测&#xff1b;开…

CVPR 2025 | 具身智能 | HOLODECK:一句话召唤3D世界,智能体的“元宇宙练功房”来了

关注gongzhonghao【CVPR顶会精选】1.导读1.1 论文基本信息论文标题&#xff1a;《HOLODECK: Language Guided Generation of 3D Embodied AI Environments》作者&#xff1a;Yue Yang*1, Fan-Yun Sun*2, Luca Weihs*4, Eli Vanderbilt4, Alvaro Herrasti4,Winson Han4, Jiajun …

迅为RK3568开发板搭建Ubuntu环境

本小节介绍开发所需 Ubuntu 环境的搭建方法。系统要求:Ubuntu 系统要求&#xff1a;Ubuntu18.04~21.10 版本。推荐使用 20.04 版本&#xff0c;内存 16GB 及以上&#xff0c;硬盘 100GB 及以上。Ubuntu 系统的用户名不能包含中文字符。建议 Ubuntu 和 Windows 系统上安装的 Dev…

【数据结构】用堆解决TOPK问题

设计一个算法&#xff0c;找出数组中最小的k个数。以任意顺序返回这k个数均可。示例&#xff1a;输入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 输出&#xff1a; [1,2,3,4]比较替换堆顶的数时&#xff0c;不需要让堆顶与数组的每一个数再进行比较&#xff0c;比较数组减去k个…

【深度长文】Anthropic发布Prompt Engineering全新指南

目录 1.什么时候适合用提示工程? 2.如何进行提示工程 2.1 使用提示模板 2.1.1 使用提示模板和变量 2.1.2 何时使用提示模板和变量 2.1.3 提示模板示例 2.2 保持清晰和直接 2.2.1 如何保持清晰、具有上下文和具体 2.2.2 示例 ​2.3 使用示例&#xff08;多示例提示…

【基础-判断】HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力

正确 解释如下: 应用加固: 这是指对应用程序进行保护,使其更难被逆向工程、篡改或盗版。HarmonyOS 作为现代操作系统,确实提供了这样的基础安全能力。 混淆: HarmonyOS 的 SDK 提供了代码混淆工具(通常基于 ProGuard 或类似技术)。开发者在构建应用时启用混淆,可以将类…

HTML 框架:构建网页布局的基石

HTML 框架&#xff1a;构建网页布局的基石 引言 HTML 框架是网页设计中不可或缺的一部分&#xff0c;它为网页内容的布局提供了强大的支持。本文将深入探讨 HTML 框架的概念、种类、应用以及如何有效地使用它们来构建网页布局。 什么是 HTML 框架&#xff1f; HTML 框架是一种网…

[Linux]学习笔记系列 -- [mm][memblock]

文章目录mm/memblock.c: Linux内核的“拓荒时代”内存管理器一、 核心问题&#xff1a;为什么需要 memblock&#xff1f;二、 核心原理与设计三、 在内核启动流程中的角色四、 关键 API五、 总结include/linux/memblock.hmm/memblock.cmemblock_reserve 预留内存块for_each_mem…

Java 面试八股文汇总(1000 道附答案解析)

在过 2 个月即将进入金九银十了&#xff0c;然而面对今年的大环境而言&#xff0c;跳槽成功的难度比往年高了很多&#xff0c;很明显的感受就是&#xff1a;对于今年的 java 开发朋友跳槽面试&#xff0c;无论一面还是二面&#xff0c;都开始考验一个 Java 程序员的技术功底和基…

给纯小白的Python操作 PDF 笔记

一、文件基础打开与关闭 推荐用 with open(path, mode, encodingutf-8) as f:&#xff0c;自动完成 close()&#xff0c;避免泄露文件句柄。常见模式&#xff1a;r 读&#xff0c;w 写覆盖&#xff0c;a 追加&#xff0c;rb/wb 二进制。Windows 默认编码为 GBK&#xff0c;Linu…

vue使用vue-cropper实现图片裁剪之单图裁剪

vue制作的pc系统中(如若依系统)&#xff0c;需要实现按照固定尺寸进行裁剪后再进行图片上传&#xff0c;以下代码讲述的是实现单张图片裁剪上传。1.第一步需要安装vue-croppernpm install vue-cropper2.第二步在需要的页面进入代码引入import {VueCropper} from "vue-crop…