Linux-线程同步(条件变量、POSIX信号量)

一、线程同步概念

        线程同步(Thread Synchronization)是多线程编程中的一个重要概念,它指的是在多线程环境中,各个线程按照一定的顺序或规则来执行,以确保数据的完整性和一致性,避免数据竞争(Data Race)和条件竞争(Race Condition)等问题。

        在多线程程序中,不同的线程可能会同时访问和修改共享资源(如内存中的变量、文件、数据库等)。如果没有适当的同步机制,就可能发生数据不一致或数据损坏的情况,因为线程的执行顺序和速度是不可预测的。

线程同步的目的主要是:

  1. 保护共享资源:确保在同一时刻只有一个线程可以访问或修改某个特定的共享资源。
  2. 维护数据一致性:通过控制对共享资源的访问顺序,确保数据在多个线程之间保持一致性和正确性。
  3. 协调线程的执行:按照预定的顺序或规则来执行线程,以避免出现不可预测的行为或结果。

实现线程同步的方法有多种,包括但不限于以下几种:

  • 互斥锁(Mutex):互斥锁是一种最基本的同步机制,用于保护共享资源,确保同一时刻只有一个线程可以访问该资源。当一个线程访问共享资源时,它会先锁定互斥锁,访问结束后释放锁,其他线程才能访问该资源。
  • 信号量(Semaphore):信号量是一种更高级的同步机制,用于控制多个线程对多个共享资源的访问。信号量本质是一个计数器,表示可用资源的数量,是一种可用资源的预订机制。线程在访问资源前,会先尝试减少信号量的计数器,如果计数器大于0,则允许访问;否则,线程将被阻塞,直到计数器大于0为止。
  • 条件变量(Condition Variable):条件变量与互斥锁一起使用,用于线程间的同步。线程在特定条件下会被阻塞,直到另一个线程改变条件并通知它。

二、条件变量

        当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。 例如一个线程访问队列时,发现队列为空,它只能等待,只到其它线程将一个节点添加到队列中,但是如果访问的这个线程竞争锁的能力比较强,他会一直申请锁--判断是否为空--释放锁,重复执行,而向队列添加数据的线程反而因为竞争不到锁导致程序无法合理执行(互斥锁只能保证同一时刻只有一个线程访问共享资源但不能保证共享资源被使用的合理性),这种情况就需要用到条件变量。

条件变量函数

1.初始化(两种方式)

方法一:静态分配

//当条件变量定义为全局的时候可以这样初始化
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;  

方法二:动态分配 

int pthread_cond_init(pthread_cond_t *restrict cond,const
pthread_condattr_t *restrict attr);
参数:
cond:要初始化的条件变量
attr:NULL

2.销毁

int pthread_cond_destroy(pthread_cond_t *cond)

3.等待条件满足

int pthread_cond_wait(pthread_cond_t *restrict
cond,pthread_mutex_t *restrict mutex);
参数:
cond:要在这个条件变量上等待
mutex:互斥量
//成功返回0,失败返回错误码.

条件等待必须与互斥锁同时使用,一般的使用逻辑是先申请锁,在判断条件,如果条件满足,就开始等待,由于等待时该线程是申请到锁的,这个阶段其他线程就无法访问共享资源了,所以等待时会先将锁释放掉,当收到唤醒信号时在重新竞争锁。

问题:为什么 pthread_cond_wait 需要互斥量?

  • 条件等待是线程间同步的一种手段,如果只有一个线程,条件不满足,一直等 下去都不会满足,所以必须要有一个线程通过某些操作,改变共享变量,使原先不 满足的条件变得满足,并且友好的通知等待在条件变量上的线程。
  • 条件不会无缘无故的突然变得满足了,必然会牵扯到共享数据的变化。所以一 定要用互斥锁来保护。没有互斥锁就无法安全的获取和修改共享数据
pthread_mutex_lock();while (condition_is_false)
{pthread_cond_wait();
}pthread_mutex_unlock();

ps、一般判断条件不用 if 而是用 while ,因为假设有个线程发送信号唤醒了两个线程,有一个线程竞争到锁了向下继续执行了,可能此时条件又不满足了,改线程虽然唤醒了但是不能竞争锁,还需要继续等待下一次的唤醒信号才能重新竞争锁,所以一般循环判断条件

唤醒等待

int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_signal(pthread_cond_t *cond);

三、POSIX 信号量

信号量回顾

信号量的本质是一个计数器,用于标识共享资源的数量,申请信号量的本质是对共享资源的预定机制,例如许多人想去电影院看电影,影院先不管你在影厅里面干什么,你想进到影厅首先需要先买票,票数其实就相当于信号量,买票就相当于预定座位,当信号量被申请完,其他人还想进影厅就得等待信号量,等其他人退票你申请到信号量才能进来

函数介绍

初始化信号量

#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
pshared:0 表示线程间共享,非零表示进程间共享
value:信号量初始值,共享资源个数

销毁信号量

int sem_destroy(sem_t *sem);

等待信号量

int sem_wait(sem_t *sem); //P()
功能:等待信号量,会将信号量的值减 1

发布信号量

int sem_post(sem_t *sem);//V()
功能:发布信号量,表示资源使用完毕,可以归还资源了。将信号量值加 1。

对于条件变量和POSIX信号量的理解,大家可以参考:张得帅c/Linux

  • 基于BlockQueue的生产消费模型
  • 基于环形队列的生产消费模型

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

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

相关文章

MATLAB quiver矢量图 设置colorbar

给三维矢量图按照不同高度设置箭头颜色 figure clf X surfaceuz(:,1); Y surfaceuz(:,2); Z surfaceuz(:,3); hold onzcolor jet; % qquiver3(X,Y,Z,X,Y,W) for i 1:length(surfaceuz)quiver3(X(i),Y(i),Z(i),X(i),Y(i), Z(i),...Color,zcolor(floor((Z(i) - -0.1) * 2…

ArgMed-Agents:通过多个智能体论证方案增强大模型,进行可解释的临床决策推理

ArgMed-Agents&#xff1a;通过多个智能体论证方案增强大模型&#xff0c;进行可解释的临床决策推理 提出背景ArgMed-Agents 框架目的解法拆解逻辑链 临床讨论的论证方案&#xff08;ASCD&#xff09;论证方案用于决策&#xff08;ASDM&#xff09;论证方案用于副作用&#xff…

构建LangChain应用程序的示例代码:65、如何使用Kay.ai获取和处理新闻稿数据

新闻稿数据 新闻稿数据由Kay.ai提供支持。 公司使用新闻稿来宣布重要事项,包括产品发布、财务业绩报告、合作关系以及其他重大新闻。分析师广泛使用新闻稿来追踪公司战略、运营更新和财务表现。 Kay.ai从多种来源获取所有美国上市公司的新闻稿,这些来源包括公司官方新闻室和与…

如何保护你的网络安全?

在2024年4月&#xff0c;一次创纪录的DDoS&#xff08;分布式拒绝服务&#xff09;攻击震惊了网络世界&#xff0c;这次攻击达到每秒840百万数据包&#xff08;Mpps&#xff09;。你可能会问&#xff0c;DDoS攻击到底是什么&#xff1f;为什么它这么重要呢&#xff1f; 什么是…

宝塔面板以www用户运行composer

方式一 执行命令时指定www用户 sudo -u www composer update方式二 在网站配置中的composer选项卡中选择配置运行

【堆 优先队列 第k大】2551. 将珠子放入背包中

本文涉及知识点 堆 优先队列 第k大 LeetCode2551. 将珠子放入背包中 你有 k 个背包。给你一个下标从 0 开始的整数数组 weights &#xff0c;其中 weights[i] 是第 i 个珠子的重量。同时给你整数 k 。 请你按照如下规则将所有的珠子放进 k 个背包。 没有背包是空的。 如果第…

汇昌联信电商做拼多多运营如何提高效率?

汇昌联信电商做拼多多运营如何提高效率?在电商领域&#xff0c;效率的高低往往直接关系到企业的成败。拼多多作为国内领先的电商平台之一&#xff0c;吸引了大量商家入驻&#xff0c;竞争异常激烈。对于汇昌联信电商而言&#xff0c;提高在拼多多平台的运营效率&#xff0c;不…

Webhook 是什么?详解其工作原理

在现代技术中&#xff0c;一切都相互连接&#xff0c;每个应用程序通过许多服务的组合和协调实现无缝工作。这种协调是通过 webhooks 实现的。 Webhooks 是基于 HTTP 的回调函数&#xff0c;其中一个服务使用 API 立即通知另一个服务发生的事件。这就是简单的版本。从技术上讲…

逆向案例二十——请求头参数加密,某政府农机购置与应用补贴申请办理服务系统,sm3和sm4的加密

网址&#xff1a;农机购置与应用补贴申请办理服务系统 抓包分析&#xff0c;发现请求头参数有加密&#xff0c;表单有加密&#xff0c;返回的数据也是加密的。 请求头Source是固定的&#xff0c;其他的Sign,以及Timsestamp是加密的 请求载荷也是加密的 返回的数据也是加密的。…

Qt实现MDI应用程序

本文记录Qt实现MDI应用程序的相关操作实现 目录 1.MDM模式下窗口的显示两种模式 1.1TabbedView 页签化显示 1.2 SubWindowView 子窗体显示 堆叠cascadeSubWindows 平铺tileSubWindows 2.MDM模式实现记录 2.1. 窗体继承自QMainWindow 2.2.增加组件MdiArea 2.3.定义统一…

“解锁物流新纪元:深入探索‘沂路畅通‘分布式协作平台“

"解锁物流新纪元&#xff1a;深入探索沂路畅通分布式协作平台" 在21世纪的数字浪潮中&#xff0c;物流行业作为连接生产与消费的关键纽带&#xff0c;其重要性不言而喻。然而&#xff0c;随着市场规模的持续扩大和消费者需求的日益多样化&#xff0c;传统物流模式已…

深度强化学习Deep Rrinforcement Learning|MDP|POMDP

目录 一、深度强化学习概述&#xff08;DRL&#xff09; 1、DRL可以获得复杂网络优化的解决方案 2、DRL允许网络实体学习和构建有关通信和网络环境的知识 3、DRL提供自主决策 4、DRL显著提高了学习速度&#xff0c;特别是在具有大状态和大动作空间的问题中 5、通信和网络中…

7月5日,自然保护地总体规划智能编制系统,线上宣讲会(腾讯会议:638-228-003)

7月5日&#xff08;本周五&#xff09;下午2:30&#xff0c;国家林草局林草调查规划院胡理乐研究员&#xff0c;介绍自然保护地总体规划智能编制系统&#xff0c;欢迎大家线上参加&#xff01;&#xff08;腾讯会议号&#xff1a;638-228-003&#xff09; 系统主要特色&#x…

【python】pandas报错:UnicodeDecodeError详细分析,解决方案以及如何避免

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

OpenMesh入门,安装,运行示例Hello World

安装 环境 win10&#xff0c;qt5 源码下载编译 进入OpenMesh官网OpenMesh官网 https://www.graphics.rwth-aachen.de/software/openmesh/download/ 使用cmake gui 注意&#xff1a;先安装qt5 使用 CMake-Gui 构建 vs 2019 项目 注意 where is the source code 是<project…

PE73_E6_BLE

PE73_E6_BLE 产品参数 产品型号 PE73_E6_BLE 尺寸(mm) 180*130*13mm 显示技术 电子墨水屏 显示区域(mm) 163.2(H) * 97.92(V) 分辨率(像素) 800*480 像素尺寸(mm) 0.204*0.204 显示颜色 黑/白/红/黄/橙/蓝/绿 视觉角度 180 工作温度 0-50℃ …

留学生该怎么进行英国essay修改润色?

新学期就要开始了&#xff0c;很多留学生是不是在烦恼怎么进行essay写作呢?英国是一个非常注重学术严谨度的国家&#xff0c;对essay的要求十分严格&#xff0c;而国内留学生初到英国&#xff0c;对语言环境和文章语法都不是那么精通&#xff0c;写出来的论文难免水平不高。那…

前端开发(基础)

目录 一、Web前端项目初始化 环境准备 创建项目 前端工程化配置 引入组件库 开发规范 全局通用布局 基础布局结构 全局底部栏 动态替换内容 全局顶部栏 通用路由菜单 支持多套布局 请求 请求工具库 全局自定义请求 自动生成请求代码 全局状态管理 全局权限管…

Ti_MSPM0开发环境搭建(keil版本)

一&#xff1a;基础软件下载 开发MSPM0的软件组合方式有很多&#xff0c;但是最常见的就是keilsysSDK或者CCSsysSDK,这里先明确一下几个软件是干什么的&#xff0c;SDK文件里面提供了Ti的案例&#xff0c;驱动等我们可以理解为他的开发环境都是基于SDK的所以这个SDK是必须要下载…

构建自动化的精粹:Gradle任务依赖性与执行顺序控制

构建自动化的精粹&#xff1a;Gradle任务依赖性与执行顺序控制 在构建自动化领域&#xff0c;Gradle以其声明式任务依赖性而著称&#xff0c;为开发者提供了强大的控制力&#xff0c;以精确定义任务的执行顺序。无论是复杂的多项目构建&#xff0c;还是单一项目的自定义构建流…