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

Linux线程同步信号量

什么是信号量(Semaphore)?

信号量(Semaphore) 是一种用于线程同步和进程间通信的机制,它用于控制多个线程对共享资源的访问。在 Linux 中,信号量通常用于防止多个线程同时访问有限的资源,从而避免出现数据竞争(race condition)和死锁(deadlock)等问题。

信号量的概念最早由计算机科学家 Edsger Dijkstra 提出,目的是用来控制对共享资源的访问。它可以看作是一个计数器,线程可以通过信号量来请求或释放资源。

信号量的类型:

在 Linux 系统中,信号量有两种主要类型:

  1. 二值信号量(Binary Semaphore):其值只能为 0 或 1,通常用于实现互斥锁(mutex),表示一个资源是否被占用。它的主要作用是控制资源的独占访问。

  2. 计数信号量(Counting Semaphore):可以取任何非负整数值,用于控制多个相同资源的访问。例如,限制同时访问某个资源的线程数量。

信号量的基本操作:

信号量通常通过两个操作来控制:

  1. P 操作(也叫 waitdown:当线程执行该操作时,如果信号量的值大于 0,它会将信号量减 1,并继续执行。如果信号量的值为 0,线程会被阻塞,直到信号量值大于 0 为止。

  2. V 操作(也叫 signalup:当线程执行该操作时,它会将信号量的值加 1,并唤醒可能被阻塞的线程。如果有线程在等待信号量,它会被唤醒并继续执行。

信号量的使用场景:

信号量广泛应用于:

  • 资源共享:信号量控制对共享资源(如缓冲区、数据库连接池等)的访问,确保多个线程或进程能够有效、安全地访问这些资源。

  • 线程同步:通过信号量实现线程之间的协调和同步,确保线程按照预定顺序执行,避免冲突和资源争用。

Linux 系统中的信号量:

在 Linux 系统中,信号量可以通过 System V 信号量POSIX 信号量 来实现。

1. System V 信号量

在 Linux 中,sysvsem 模块提供了 System V 信号量的实现,主要使用 semgetsemopsemctl 系统调用来管理信号量。

  • semget:创建或获取信号量集。

  • semop:执行信号量操作。

  • semctl:控制信号量集的操作(例如,删除信号量)。

2. POSIX 信号量

POSIX 信号量的 API 是更加现代化的,并且通常与线程库一起使用。可以通过 sem_initsem_waitsem_postsem_destroy 来操作信号量。

  • sem_init:初始化信号量。

  • sem_wait:P 操作(等待信号量)。

  • sem_post:V 操作(释放信号量)。

  • sem_destroy:销毁信号量。

示例:使用 POSIX 信号量进行线程同步

下面是一个简单的例子,演示了如何在多线程程序中使用 POSIX 信号量来同步线程。

代码示例:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
​
sem_t sem;  // 信号量
​
// 线程函数
void* thread_function(void* arg) {// P 操作:等待信号量sem_wait(&sem);printf("Thread %ld is in critical section.\n", (long)arg);// 模拟工作sleep(2);printf("Thread %ld is leaving critical section.\n", (long)arg);// V 操作:释放信号量sem_post(&sem);return NULL;
}
​
int main() {pthread_t threads[3];// 初始化信号量,初始值为 1(即一个线程可以访问临界区)sem_init(&sem, 0, 1);// 创建多个线程for (long i = 0; i < 3; i++) {pthread_create(&threads[i], NULL, thread_function, (void*)i);}// 等待所有线程结束for (int i = 0; i < 3; i++) {pthread_join(threads[i], NULL);}// 销毁信号量sem_destroy(&sem);return 0;
​
}
解释:
  • sem_init(&sem, 0, 1):初始化一个信号量,初始值为 1。这意味着最多只有一个线程能够进入临界区(即最多一个线程能访问共享资源)。

  • sem_wait(&sem):在进入临界区之前,每个线程都会执行 P 操作,减少信号量的值。如果信号量为 0,线程将被阻塞,直到信号量大于 0。

  • sem_post(&sem):线程执行完临界区的操作后,执行 V 操作,增加信号量的值,释放信号量,允许其他线程进入临界区。

  • sem_destroy(&sem):在程序结束时销毁信号量,释放相关资源。

结果:
Thread 0 is in critical section.
Thread 0 is leaving critical section.
Thread 1 is in critical section.
Thread 1 is leaving critical section.
Thread 2 is in critical section.
Thread 2 is leaving critical section.

在这个程序中,信号量确保只有一个线程能够进入临界区(即最多只有一个线程同时执行打印操作),这避免了多个线程同时访问临界区可能带来的问题。

总结:

  • 信号量 是用于线程同步和进程间通信的机制,主要有二值信号量和计数信号量两种类型。

  • 信号量通过 P 操作(sem_wait)和 V 操作(sem_post)来控制对共享资源的访问。

  • 在 Linux 中,可以使用 POSIX 信号量(sem_initsem_waitsem_postsem_destroy)或者 System V 信号量(semgetsemopsemctl)来实现线程同步。

  • 信号量是一种强大的同步机制,广泛应用于多线程程序中,避免了数据竞争和资源冲突。

相关文章:

Linux线程同步信号量

什么是信号量&#xff08;Semaphore&#xff09;&#xff1f; 信号量&#xff08;Semaphore&#xff09; 是一种用于线程同步和进程间通信的机制&#xff0c;它用于控制多个线程对共享资源的访问。在 Linux 中&#xff0c;信号量通常用于防止多个线程同时访问有限的资源&#…...

日志系统**

1.设置日志级别 enum LogLevel{TRACE,DEBUG,INFO,WARN,ERROR,FATAL,NUM_LOG_LEVELS,}; 2.日志格式 TimeStamp 级别 内容 [2025-05-17 20:32:41][ERROR]This is an error message 3.输出&#xff1a;控制台/文件 4.注意 #include <chrono> #include <iomanip&g…...

【C++】18.二叉搜索树

由于map和set的底层是红黑树&#xff0c;同时后面要讲的AVL树(高度平衡二叉搜索树)&#xff0c;为了方便理解&#xff0c;我们先来讲解二叉搜索树&#xff0c;因为红黑树和AVL树都是在二叉搜索树的前提下实现的 在之前的C语言数据结构章节中&#xff0c;我们讲过二叉树&#x…...

刘家祎双剧收官见证蜕变,诠释多面人生

近期&#xff0c;两部风格迥异的剧集迎来收官时刻&#xff0c;而青年演员刘家祎在《我家的医生》与《无尽的尽头》中的精彩演绎&#xff0c;无疑成为观众热议的焦点。从温暖治愈的医疗日常到冷峻深刻的少年救赎&#xff0c;他以极具张力的表演&#xff0c;展现出令人惊叹的可塑…...

python + streamlink 下载 vimeo 短视频

1. 起因&#xff0c; 目的: 看到一个视频&#xff0c;很喜欢&#xff0c;想下载。https://player.vimeo.com/video/937787642 2. 先看效果 能下载。 3. 过程: 因为我自己没头绪。先看一下别人的例子&#xff0c; 问一下 ai 或是 google问了几个来回&#xff0c;原来是流式…...

18-总线IIC

一、IIC 1、IIC概述 I2C(IIC,Inter&#xff0d;Integrated Circuit),两线式串行总线,由PHILIPS&#xff08;飞利浦&#xff09;公司开发用于连接微控制器及其外围设备。 它是由数据线SDA和时钟SCL构成的串行总线&#xff0c;可发送和接收数据。在CPU与被控IC之间、IC与IC之间…...

【深度学习-Day 12】从零认识神经网络:感知器原理、实现与局限性深度剖析

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

力扣HOT100之二叉树:98. 验证二叉搜索树

这道题之前也刷过&#xff0c;自己做了一遍&#xff0c;发现卡在了第70多个样例&#xff0c;才发现自己没有利用二叉搜索树的性质&#xff0c;但凡涉及到二叉搜索树&#xff0c;应该首先考虑中序遍历&#xff01;&#xff01;&#xff01; 被卡住的测试样例是这样的&#xff1a…...

vector(c++)

前言 正式进入学习STL的第一步就是vector容器&#xff0c; vector是一种用于存储可变大小数组的序列容器&#xff0c;就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。本质上讲&#xff0c;vector使用动态分配数组来存储它的元素。底层是一个顺序表。本文介绍…...

CAPL Class: TcpSocket (此类用于实现 TCP 网络通信 )

目录 Class: TcpSocketacceptopenclosebindconnectgetLastSocketErrorgetLastSocketErrorAsStringlistenreceivesendsetSocketOptionshutdown函数调用的基本流程服务器端的基本流程客户端的基本流程Class: TcpSocket学习笔记。来自CANoe帮助文档。 Class: TcpSocket accept /…...

C语言:gcc 如何调用 Win32 打开文件对话框 ?

在 Windows 平台上使用 gcc 调用原生 Win32 API 实现文件打开对话框是可行的&#xff0c;但需要直接使用 Win32 的 GetOpenFileName 函数&#xff08;位于 commdlg.h 头文件&#xff0c;依赖 comdlg32.lib 库&#xff09;。以下是完整实现步骤和代码示例&#xff1a; 编写 file…...

OpenHarmony:开源操作系统重塑产业数字化底座

OpenHarmony&#xff1a;开源操作系统重塑产业数字化底座 引言&#xff1a;当操作系统成为数字公共品 在万物智联时代&#xff0c;操作系统不再是科技巨头的专属领地。华为捐赠的OpenHarmony项目&#xff0c;正以开源协作模式重构操作系统产业格局。这个脱胎于商业版本的开源…...

线程同步学习

概念 有A、B、C三个线程&#xff0c;A线程负责输入数据&#xff0c;B线程负责处理数据、C线程负责输出数据&#xff0c;这三个线程之间就存在着同步关系&#xff0c;即A必须先执行&#xff0c;B次之&#xff0c;C最后执行&#xff0c;否则不能得到正确的结果。 那么所谓线程同…...

十二、Hive 函数

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月17日 专栏&#xff1a;Hive教程 在数据处理的广阔天地中&#xff0c;我们常常需要对数据进行转换、计算、清洗或提取特定信息。Hive 提供了强大的内置运算符和丰富的内置函数库&#xff0c;它们就像魔法师手中的魔法棒&…...

DeepSeek 赋能社会科学:解锁研究新范式

目录 一、DeepSeek&#xff1a;大语言模型中的新力量1.1 DeepSeek 技术亮点1.2 与其他模型对比 二、DeepSeek 在社会科学研究中的应用领域2.1 经济学研究2.2 社会学研究2.3 历史学研究2.4 法学研究 三、DeepSeek 应用案例深度剖析3.1 案例一&#xff1a;社会学研究中社会舆情分…...

java函数内的变量问题

public class VendingMachine {//设计一个类叫做VendingMachine,用这个类制造一个对象vmint price 80;int balance;//三个属性int total;void showprompt(){System.out.println("Welcome");}void insertmoney(int amount){balance balance amount;}void showBalan…...

docker部署第一个Go项目

1.前期准备 目录结构 main.go package mainimport ("fmt""github.com/gin-gonic/gin""net/http" )func main() {fmt.Println("\n .::::.\n .::::::::.\n :::::::::::\n …...

【读代码】端到端多模态语言模型Ultravox深度解析

一、项目基本介绍 Ultravox是由Fixie AI团队开发的开源多模态大语言模型,专注于实现音频-文本的端到端实时交互。项目基于Llama 3、Mistral等开源模型,通过创新的跨模态投影架构,绕过了传统语音识别(ASR)的中间步骤,可直接将音频特征映射到语言模型的高维空间。 核心优…...

管理前端项目依赖版本冲突导致启动失败的问题的解决办法

管理前端项目依赖版本冲突导致启动失败的问题&#xff0c;可按照以下步骤系统解决&#xff1a; 1. 定位冲突来源 查看错误日志&#xff1a;启动失败时的控制台报错通常会指出具体模块或版本问题&#xff0c;例如 Module not found 或 TypeError。检查依赖树&#xff1a;npm l…...

北京市工程技术人才职称评价基本标准条件解读

北京市工程技术人才职称评价基本标准条件 北京市工程技术人才之技术员 北京市工程技术人才之助理工程师 北京市工程技术人才之工程师 北京市工程技术人才之高级工程师 北京市工程技术人才之高级工程师&#xff08;破格&#xff09; 北京市工程技术人才之正高级工程师 北京市工程…...

MUSE Pi Pro 开发板 Imagination GPU 利用 OpenCL 测试

视频讲解&#xff1a; MUSE Pi Pro 开发板 Imagination GPU 利用 OpenCL 测试 继续玩MUSE Pi Pro&#xff0c;今天看下比较关注的gpu这块&#xff0c;从opencl看起&#xff0c;安装clinfo指令 sudo apt install clinfo 可以看到这颗GPU是Imagination的 一般嵌入式中gpu都和hos…...

Mysql数据库之集群进阶

一、日志管理 5.7版本自定义路径时的文件需要自己提前创建好文件&#xff0c;不会自动创建&#xff0c;否则启动mysql会报错 错误日志 rpm包(yum) /var/log/mysql.log 默认错误日志 ###查询日志路径 [rootdb01 ~]# mysqladmin -uroot -pEgon123 variables | grep -w log_e…...

JavaScript防抖与节流全解析

文章目录 前言:为什么需要防抖和节流基本概念与区别防抖(Debounce)节流(Throttle)关键区别防抖(Debounce)详解1. 基本防抖函数实现2. 防抖函数的使用3. 防抖函数的工作流程4. 防抖函数进阶 - 立即执行选项节流(Throttle)详解1. 基本节流函数实现时间戳法(第一次会立即执行)定…...

大模型学习:Deepseek+dify零成本部署本地运行实用教程(超级详细!建议收藏)

文章目录 大模型学习&#xff1a;Deepseekdify零成本部署本地运行实用教程&#xff08;超级详细&#xff01;建议收藏&#xff09;一、Dify是什么二、Dify的安装部署1. 官网体验2. 本地部署2.1 linux环境下的Docker安装2.2 Windows环境下安装部署DockerDeskTop2.3启用虚拟机平台…...

在RK3588上使用NCNN和Vulkan加速ResNet50推理全流程

在RK3588上使用NCNN和Vulkan加速ResNet50推理全流程 前言:为什么需要关注移动端AI推理一、环境准备与框架编译1.1 获取NCNN源码1.2 安装必要依赖1.3 编译NCNN二、模型导出与转换2.1 生成ONNX模型2.2 转换NCNN格式三、模型量化加速3.1 生成校准数据3.2 执行量化操作四、性能测试…...

Web安全基础:深度解析与实战指南

一、Web安全体系架构的全面剖析 1.1 分层防御模型(Defense in Depth) 1.1.1 网络层防护 ​​防火墙技术​​: 状态检测防火墙(SPI):基于连接状态跟踪,阻断非法会话(如SYN Flood攻击)下一代防火墙(NGFW):集成IPS、AV、URL过滤(如Palo Alto PA-5400系列)配置示例…...

Uniapp开发鸿蒙应用时如何运行和调试项目

经过前几天的分享&#xff0c;大家应该应该对uniapp开发鸿蒙应用的开发语法有了一定的了解&#xff0c;可以进行一些简单的应用开发&#xff0c;今天分享一下在使用uniapp开发鸿蒙应用时怎么运行到鸿蒙设备&#xff0c;并且在开发中怎么调试程序。 运行 Uniapp项目支持运行到…...

Python海龟绘图(Turtle Graphics)核心函数和关键要点

以下是Python海龟绘图&#xff08;Turtle Graphics&#xff09;的核心函数和关键要点整理&#xff1a; 一、画布设置 函数/方法说明参数说明备注turtle.setup(width, height, x, y)设置画布尺寸和位置width宽度&#xff0c;height高度&#xff0c;x/y窗口左上角坐标默认尺寸80…...

如何在Cursor中高效使用MCP协议

1、Cursor介绍 Cursor是一个功能强大的开发工具&#xff0c;内置了聊天助手、代码自动补全和调试工具&#xff0c;能够与多种外部工具和服务&#xff08;如数据库、文件系统、浏览器等&#xff09;进行深度集成。借助MCP&#xff08;Multiverse Communication Protocol&#x…...

典籍知识问答模块AI问答bug修改

一、修改流式数据处理问题 1.问题描述&#xff1a;由于传来的数据形式如下&#xff1a; event:START data:350 data:< data:t data:h data:i data:n data:k data:> data: data: data: data: data:嗯 data:&#xff0c; 导致需要修改获取正常的当前信息id并更…...

Redis 发布订阅模式深度解析:原理、应用与实践

在现代分布式系统架构中&#xff0c;实时消息传递机制扮演着至关重要的角色。Redis 作为一款高性能的内存数据库&#xff0c;其内置的发布订阅(Pub/Sub)功能提供了一种轻量级、高效的消息通信方案。本文将全面剖析 Redis 发布订阅模式&#xff0c;从其基本概念、工作原理到实际…...

通义千问-langchain使用构建(三)

目录 序言docker 部署xinference1WSL环境docker安装2拉取镜像运行容器3使用的界面 本地跑chatchat1rag踩坑2使用的界面2.1配置个前置条件然后对话2.2rag对话 结论 序言 在前两天的基础上&#xff0c;将xinference调整为wsl环境&#xff0c;docker部署。 然后langchain chatcha…...

c++ 仿函数

示例代码&#xff1a; void testFunctor() {using Sum struct MyStruct {int operator() (int a, int b) const { // 重载&#xff08;&#xff09;运算符return a b;}};Sum sum;std::cout << sum(9528, -1) << std::endl; } 打印&#xff1a; 仿函数意思是&am…...

hyper-v 虚拟机怎么克隆一台一样的虚拟机?

环境&#xff1a; hyper-v Win10专业版 问题描述&#xff1a; hyper-v 虚拟机怎么克隆一台一样的虚拟机&#xff1f; 解决方案&#xff1a; 以下是在 Hyper-V 中克隆虚拟机的几种方法&#xff1a; 方法一&#xff1a;使用导出和导入功能 导出虚拟机&#xff1a; 打开 H…...

操作系统:os概述

操作系统&#xff1a;OS概述 程序、进程与线程无极二级目录三级目录 程序、进程与线程 指令执行需要那些条件&#xff1f;CPU内存 需要数据和 无极 二级目录 三级目录...

【技巧】GoogleChrome浏览器开发者模式查看dify接口

回到目录 GoogleChrome浏览器开发者模式查看dify接口 1.搭建本地dify开发环境 参考 《 win10的wsl环境下调试dify的api后端服务(20250511发布)》 2.打开dify首页&#xff0c;进入开发者模式&#xff0c;Network页 勾选 Preserve log [图1] 3.填好用户名和密码&#xff0c;…...

Ocean: Object-aware Anchor-free Tracking

领域&#xff1a;Object tracking It aims to infer the location of an arbitrary target in a video sequence, given only its location in the first frame 问题/现象&#xff1a; Anchor-based Siamese trackers have achieved remarkable advancements in accuracy, yet…...

java中的循环结构

文章目录 流程控制顺序结构if单选择结构if双选择结构if多选择结构嵌套的if结构switch多选择结构 循环结构while循环do...while循环 for循环增强for循环 break continue练习案例 流程控制 顺序结构 java的基本结果就是顺序结构&#xff0c;除非特别指明&#xff0c;否则就按照…...

数学复习笔记 16

前言 例题真是经典。 background music 《青春不一样》 2.28 算一个行列式&#xff0c;算出来行列式不等于零&#xff0c;这表示矩阵式可逆的。但是这个算的秩是复合的&#xff0c;感觉没啥好办法了&#xff0c;我直接硬算了&#xff0c;之后再看解析积累好的方法。算矩阵…...

PySide6 GUI 学习笔记——常用类及控件使用方法(常用类颜色QColor)

文章目录 一、概述二、核心功能三、常用函数及方法四、代码示例五、注意事项 一、概述 QColor 是用于处理颜色的类&#xff0c;支持 RGB、HSV、HSL、CMYK 等多种颜色模型&#xff0c;提供颜色创建、转换、分量操作及格式转换功能。支持透明度设置&#xff0c;可通过颜色名称或…...

【Closure-Hayd】

RNA序列本身存在结构上的物理信息&#xff0c;因此可以利用文献提供的相关方法来对RNA序列的物理特征进行更加细致的提取。 几何向量编码&#xff08;GVP模块&#xff09;​借鉴Rhodesign模型中的GVP&#xff08;Geometric Vector Perceptron&#xff09;模块&#xff0c;将每个…...

MySQL高可用架构

一、读写分离在高可用架构中的核心作用 1.读写分离与高可用的协同价值 在MySQL高可用架构中&#xff0c;读写分离不仅是性能优化的手段&#xff0c;更是提升系统容错能力的关键策略。通过将写操作&#xff08;INSERT、UPDATE、DELETE&#xff09; 集中到主节点&#xff0c;读…...

粒子群算法(PSO算法)

粒子群算法概述 1.粒子群优化算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;。粒子群优化算法是在1995年由Kennedy博士和Eberhart博士一起提出的&#xff0c;它源于对鸟群捕食行为的研究。 2.基本核心是利用群体中的个体对信息的共享从而使得整…...

信道编码技术介绍

信息与通信系统中的编码有4 种形式&#xff1a;信源编码、信道编码、密码编码和多址编码。 其中信道编码的作用是对信源经过压缩后的数据加一定数量受到控制的冗余&#xff0c;使得数据在传输中或接收中发生的差错可以被纠正或被发现&#xff0c;从而可以正确恢复出原始数据信息…...

JavaScript【4】数组和其他内置对象(API)

1.数组: 1.概述: js中数组可理解为一个存储数据的容器,但与java中的数组不太一样;js中的数组更像java中的集合,因为此集合在创建的时候,不需要定义数组长度,它可以实现动态扩容;js中的数组存储元素时,可以存储任意类型的元素,而java中的数组一旦创建后,就只能存储定义类型的元…...

【背包dp-----分组背包】------(标准的分组背包【可以不装满的 最大价值】)

通天之分组背包 题目链接 题目描述 自 01 01 01 背包问世之后&#xff0c;小 A 对此深感兴趣。一天&#xff0c;小 A 去远游&#xff0c;却发现他的背包不同于 01 01 01 背包&#xff0c;他的物品大致可分为 k k k 组&#xff0c;每组中的物品相互冲突&#xff0c;现在&a…...

docker-compose——安装mongo

编写docker-compose.yml version : 3.8services:zaomeng-mongodb:container_name: zaomeng-mongodbimage: mongo:latestrestart: alwaysports:- 27017:27017environment:- MONGO_INITDB_ROOT_USERNAMEroot- MONGO_INITDB_ROOT_PASSWORDpssw0rdvolumes:- ./mongodb/data:/data/…...

day 28

类 一个常见的类的定义包括了&#xff1a; 1. 关键字class 2. 类名 3. 语法固定符号冒号(:) 4. 一个初始化函数__init__(self) Pass占位符和缩进 Python 通过缩进来定义代码块的结构。当解释器遇到像 def, class, if, for 这样的语句&#xff0c;并且后面跟着冒号 : 时&…...

JavaScript入门【1】概述

1.JavaScript是什么? <font style"color:rgb(38,38,38);">Javascript &#xff08;简称“JS”&#xff09;是⼀种直译式脚本语⾔&#xff0c;⼀段脚本其实就是⼀系列指令&#xff0c;计算机通过这些指令来达成⽬标。它⼜是⼀种动态类型的编程语⾔。JS⽤来在⽹…...

MySQL 中 JOIN 和子查询的区别与使用场景

目录 一、JOIN:表连接1.1 INNER JOIN:内连接1.2 LEFT JOIN:左连接1.3 RIGHT JOIN:右连接1.4 FULL JOIN:全连接二、子查询:嵌套查询2.1 WHERE 子句中的子查询2.2 FROM 子句中的子查询2.3 SELECT 子句中的子查询三、JOIN 和子查询的区别3.1 功能差异3.2 性能差异3.3 使用场…...