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

【Linux开发】03Linux 线程同步:信号量(Semaphore)

一、问题互斥量只能“锁”不能“排队”前面我们学习了互斥量它可以解决多个线程同时访问共享资源的问题保证同一时间只有一个线程进入临界区。但互斥量只能做到“互斥”无法控制线程的执行顺序。1.1 需要控制顺序的场景假设有两个线程线程 A读取用户输入的数字存入全局变量num。线程 B将num累加到总和sum中。我们希望A 先输入 → B 再累加 → A 再输入 → B 再累加如此交替 5 次。如果用互斥量只能保证 A 和 B 不会同时操作num但不能保证 A 先执行还是 B 先执行。可能出现 B 试图累加时A 还没输入num还是旧值导致错误。1.2 需要一种能“同步顺序”的机制我们需要一种工具不仅能互斥访问还能让线程按指定的顺序执行。比如初始时只允许 A 运行B 等待。A 完成输入后通知 B 可以运行A 自己等待。B 累加后通知 A 可以继续输入B 等待。这种机制就是信号量Semaphore。二、什么是信号量2.1 概念停车场的计数器想象一个停车场门口有一个电子牌显示剩余车位数量每进入一辆车剩余车位减 1P 操作。每离开一辆车剩余车位加 1V 操作。如果剩余车位为 0后面来的车必须等待。信号量就是一个整数计数器它支持两种原子操作P等待如果计数器 0则减 1 并继续否则阻塞等待。V发信号计数器加 1并唤醒一个等待的线程如果有。2.2 二进制信号量与计数信号量二进制信号量值只能是 0 或 1相当于互斥量但功能更强可用于顺序控制。计数信号量值可以大于 1用于控制同时访问资源的线程数量如连接池。2.3 与互斥量的区别特性互斥量信号量作用互斥访问互斥 顺序控制值范围0 或 10 ~ n谁可以解锁只能加锁的线程解锁任何线程都可以 V 操作典型用途保护临界区生产者-消费者、顺序同步三、信号量相关函数信号量 API 与互斥量类似但属于 POSIX 标准头文件semaphore.h。3.1 初始化sem_init#includesemaphore.hintsem_init(sem_t*sem,intpshared,unsignedintvalue);sem指向信号量变量的指针。pshared0 表示线程间使用同一进程非 0 表示进程间使用需共享内存。value信号量的初始值。返回值成功返回 0失败返回 -1。3.2 等待P 操作sem_waitintsem_wait(sem_t*sem);如果信号量值 0将其减 1 并立即返回。如果信号量值 0线程阻塞直到值变为正数被其他线程sem_post。3.3 发信号V 操作sem_postintsem_post(sem_t*sem);将信号量值加 1。如果有线程正在等待该信号量则唤醒其中一个。3.4 销毁sem_destroyintsem_destroy(sem_t*sem);销毁信号量释放资源。四、完整示例控制线程执行顺序4.1 需求线程 A循环 5 次每次从键盘输入一个数字存入num。线程 B循环 5 次每次将num累加到sum。必须严格按照A 输入 → B 累加 → A 输入 → B 累加的顺序执行。4.2 设计思路使用两个信号量sem_one初始值为 0控制线程 B 是否可以累加。B 执行前sem_wait(sem_one)初始为 0所以 B 阻塞A 输入后sem_post(sem_one)值变为 1B 被唤醒。sem_two初始值为 1控制线程 A 是否可以输入。A 执行前sem_wait(sem_two)初始为 1A 可以立即执行输入后sem_post(sem_one)A 再次循环时会sem_wait(sem_two)等待 B 完成累加并sem_post(sem_two)。流程A 先执行sem_wait(sem_two)初始 1 → 0输入数字。A 执行sem_post(sem_one)0 → 1唤醒 B。A 回到循环开始执行sem_wait(sem_two)此时值为 0A 阻塞。B 执行sem_wait(sem_one)1 → 0累加。B 执行sem_post(sem_two)0 → 1唤醒 A。重复 5 次。4.3 完整代码#includestdio.h#includepthread.h#includesemaphore.hstaticsem_tsem_one;// 控制 B 是否可以累加staticsem_tsem_two;// 控制 A 是否可以输入staticintnum;// 共享变量void*read(void*arg){for(inti0;i5;i){// 等待许可初始 sem_two 为 1所以第一次直接通过sem_wait(sem_two);printf(Input num: );scanf(%d,num);// 通知 B 可以累加sem_post(sem_one);}returnNULL;}void*accu(void*arg){intsum0;for(inti0;i5;i){// 等待 A 输入sem_wait(sem_one);sumnum;// 通知 A 可以输入下一个数字sem_post(sem_two);}printf(Result: %d\n,sum);returnNULL;}intmain(){pthread_tt1,t2;// 初始化信号量sem_init(sem_one,0,0);// 初始为 0B 一开始会阻塞sem_init(sem_two,0,1);// 初始为 1A 可以立即执行pthread_create(t1,NULL,read,NULL);pthread_create(t2,NULL,accu,NULL);pthread_join(t1,NULL);pthread_join(t2,NULL);sem_destroy(sem_one);sem_destroy(sem_two);return0;}4.4 运行结果Input num: 10 Input num: 20 Input num: 30 Input num: 40 Input num: 50 Result: 150每次输入一个数程序就会累加不会出现 B 抢在 A 前面运行的情况。五、信号量与互斥量的对比场景使用互斥量使用信号量保护共享数据✅ 适合✅ 也可二进制信号量控制执行顺序❌ 无法实现✅ 非常适合允许多个线程同时访问如连接池❌ 只能一个✅ 计数信号量解锁者限制必须加锁者解锁任何线程都可以 V 操作六、常见问题与注意事项6.1 忘记初始化信号量sem_tsem;// 忘记 sem_init直接使用会导致未定义行为。6.2 信号量值溢出sem_post可能使信号量值超过初始设定的最大值通常是SEM_VALUE_MAX但一般不会手动设置极大值。6.3 死锁如果两个线程互相等待对方sem_post且初始值设置不当可能造成死锁。例如两个信号量初始都为 0两个线程都先sem_wait对方就会死锁。6.4 进程间信号量如果pshared非 0信号量可用于不同进程需放在共享内存中。初学者先掌握线程间使用pshared0。6.5 编译链接需要链接pthread库同时也要链接rt某些系统需要-lrt但通常-pthread已包含gcc-pthreadsem_example.c-osem_example七、总结概念说明信号量一个整数计数器支持原子增减和阻塞等待P 操作wait值减 1若值为 0 则阻塞V 操作post值加 1唤醒等待线程二进制信号量值 0/1类似互斥量计数信号量值 1控制并发数量顺序控制通过两个信号量可以实现线程交替执行信号量使用四步曲1. sem_init(sem, 0, 初始值) // 初始化 2. sem_wait(sem) // 等待P 3. sem_post(sem) // 发信号V 4. sem_destroy(sem) // 销毁

相关文章:

【Linux开发】03Linux 线程同步:信号量(Semaphore)

一、问题:互斥量只能“锁”,不能“排队” 前面我们学习了互斥量,它可以解决多个线程同时访问共享资源的问题,保证同一时间只有一个线程进入临界区。但互斥量只能做到“互斥”,无法控制线程的执行顺序。 1.1 需要控制顺…...

从字典选择到结果分析:dirsearch高效扫描的完整工作流(含SecLists实战)

从字典选择到结果分析:dirsearch高效扫描的完整工作流(含SecLists实战) 在Web安全评估和渗透测试中,目录扫描是发现潜在攻击面的关键步骤。传统的手工探测方式效率低下,而盲目使用默认配置的扫描工具又会产生大量无效结…...

Claude 长文档处理怎么做分块与上下文组织

很多开发者都知道 Claude 适合处理长文档。 但真正落到工程里,效果好不好,往往不取决于模型本身,而取决于你怎么组织输入。 说得更直接一点,长文档处理最常见的误区不是模型不够强,而是团队把一大堆原始材料直接塞进去…...

Linux 线程:从虚拟地址空间到 POSIX 线程控制全解析

前言在 Linux 系统编程与操作系统原理中,线程是并发执行的核心单元,而虚拟地址空间与分页机制是线程共享资源、轻量化运行的底层基石。本文将从线程本质、内存管理原理、进程线程对比、POSIX 线程控制、地址空间布局到线程封装,层层拆解 Linu…...

个人创作者必看:靠谱知识付费平台实测,热门排行榜推荐

对于个人创作者来说,知识付费的核心的是“内容变现”,而选对靠谱的平台,就是打通变现路径的关键一步。不少创作者明明有优质内容,却因选错平台,要么被复杂操作劝退,要么无法沉淀私域用户,要么收…...

实战指南:构建坚不可摧的vCenter HA高可用集群

1. 为什么你的企业需要vCenter HA高可用集群 记得去年有个客户半夜给我打电话,说他们的vCenter突然宕机,整个虚拟化平台瘫痪了。当时正是业务高峰期,损失惨重。这就是典型的单点故障问题——vCenter作为整个vSphere环境的大脑,一旦…...

类型声明不再“形同虚设”:PHP 8.9运行时类型验证增强如何让CI失败率下降67%?

第一章:PHP 8.9类型系统增强的演进背景与核心价值PHP 类型系统自 PHP 7 引入标量类型声明和返回类型以来,持续向静态可分析、运行时安全、开发者友好的方向演进。PHP 8.9 并非官方已发布的版本(截至 2024 年,PHP 最新稳定版为 8.3…...

程序员必备!8个无广告在线小工具,调试效率直接翻倍

程序员必备!8个无广告在线小工具,调试效率直接翻倍 日常开发中,经常会遇到各种琐碎的数据处理需求:接口返回的JSON格式混乱、时间戳不知道怎么转日期、URL参数需要编码解码…… 网上找的工具要么弹窗广告满天飞,要么功…...

msgpack Golang查询功能揭秘:高效提取序列化数据的完整指南

msgpack Golang查询功能揭秘:高效提取序列化数据的完整指南 【免费下载链接】msgpack msgpack.org[Go] MessagePack encoding for Golang 项目地址: https://gitcode.com/gh_mirrors/msg/msgpack 想要在Golang项目中快速提取MessagePack序列化数据中的特定字…...

m4s-converter:B站缓存视频本地化工具 3步实现媒体文件自主管理

m4s-converter:B站缓存视频本地化工具 3步实现媒体文件自主管理 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter 一、问题象限&#x…...

Phi-4-mini-reasoning Chainlit前端定制:添加历史记录与多会话管理功能

Phi-4-mini-reasoning Chainlit前端定制:添加历史记录与多会话管理功能 1. 项目背景与目标 Phi-4-mini-reasoning是一个基于合成数据构建的轻量级开源模型,专注于高质量、密集推理的数据处理。该模型支持128K令牌的上下文长度,特别适合需要…...

Gemma-3-270m在QT桌面应用中的集成开发指南

Gemma-3-270m在QT桌面应用中的集成开发指南 1. 引言 想在桌面应用中添加智能对话功能吗?Gemma-3-270m这个轻量级AI模型可能正是你需要的解决方案。作为Google最新推出的紧凑型语言模型,它只有2.7亿参数,却能在普通电脑上流畅运行&#xff0…...

大语言模型长输入性能研究

研究大语言模型的特性:Maxime Meyer访谈录 在本系列访谈中,我们与AAAI/SIGAI博士联盟的部分参与者进行了交流,以深入了解他们的研究。我们与Maxime Meyer坐下来聊了聊他当前的研究、未来计划以及博士联盟的经历。 能否先介绍一下你自己、你在…...

HsMod:炉石传说终极模改插件,5个核心功能让游戏体验翻倍

HsMod:炉石传说终极模改插件,5个核心功能让游戏体验翻倍 【免费下载链接】HsMod Hearthstone Modification Based on BepInEx 项目地址: https://gitcode.com/GitHub_Trending/hs/HsMod 你是否曾经在炉石传说中感到等待时间过长?是否希…...

【PHP 8.9类型革命】:从nullable到intersection,从static返回到inferable closures——12个必须掌握的类型语法变更清单

第一章:PHP 8.9类型系统演进全景图PHP 8.9尚未正式发布,但根据PHP开发团队在RFC草案与内部路线图中的持续披露,其类型系统将围绕“静态可推导性”与“运行时契约强化”双主线进行深度重构。该版本并非简单叠加新语法,而是对类型声…...

打破输入法壁垒:一站式词库转换解决方案

打破输入法壁垒:一站式词库转换解决方案 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 你是否曾因更换输入法而不得不放弃积累了多年的个人词库&#xf…...

PE文件分析工具:提升逆向工程效率的专业解决方案

PE文件分析工具:提升逆向工程效率的专业解决方案 【免费下载链接】PEExplorerV2 Portable Executable Explorer version 2 项目地址: https://gitcode.com/gh_mirrors/pe/PEExplorerV2 在软件安全与逆向工程领域,深入理解可执行文件结构是一项核心…...

SSC TOOL 5.13保姆级配置教程:手把手教你生成EtherCAT从站协议栈代码

SSC TOOL 5.13实战指南:从零构建EtherCAT从站协议栈 在工业自动化领域,EtherCAT因其卓越的实时性能和灵活的拓扑结构,已成为运动控制系统的首选通信协议。作为EtherCAT从站开发的核心工具,SSC TOOL 5.13能够将复杂的协议栈配置转化…...

3步掌握OpenCore配置工具:黑苹果引导的图形化解决方案

3步掌握OpenCore配置工具:黑苹果引导的图形化解决方案 【免费下载链接】OpenCore-Configurator A configurator for the OpenCore Bootloader 项目地址: https://gitcode.com/gh_mirrors/op/OpenCore-Configurator 你是否曾为黑苹果系统的引导配置而头疼&…...

XUnity.AutoTranslator:免费实现Unity游戏实时翻译的终极指南

XUnity.AutoTranslator:免费实现Unity游戏实时翻译的终极指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾因语言障碍而错过优秀的Unity游戏?XUnity.AutoTranslator正是…...

平台整治学历营销,创作者该如何破局?

平台整治学历营销,创作者需转向内容核心。主流社交平台已启动专项规范,对过度绑定名校标签、靠学历博眼球的内容进行规范引导,不再允许单纯以“名校”为噱头引流,引导创作者回归内容本身,摒弃“靠学历吸睛”的流量捷径…...

PMP证书到底有什么用?考证后没含金量?真相扎心但实用

最近刷CSDN,总能看到不少同行吐槽:“花大几千考了PMP,持证大半年,薪资没涨、职位没动,感觉这证就是个摆设,一点含金量都没有”。甚至有人直言“PMP就是智商税,不如多写几行代码、多做几个项目实…...

教育应用:OpenClaw+Qwen3.5-9B自动批改编程作业

教育应用:OpenClawQwen3.5-9B自动批改编程作业 1. 为什么需要自动化编程作业批改 作为一名计算机课程助教,我每周需要批改近百份学生作业。传统手动批改面临三个痛点:时间消耗大(平均每份作业15分钟)、反馈标准化程度…...

BetterNCM插件管理器:突破音乐体验边界的全能工具

BetterNCM插件管理器:突破音乐体验边界的全能工具 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 你是否曾因网易云音乐的功能局限而感到遗憾?想自定义界面却无…...

打卡信奥刷题(3081)用C++实现信奥题 P7069 [NWRRC 2014] Joy of Flight

P7069 [NWRRC 2014] Joy of Flight 题目描述 大意就是一架飞机要从起点飞到终点,飞机有最大空速,飞行最大时间,给出风速的变化和风如何影响飞机飞行,求出飞机是否能到达终点,如果能就输出飞机的位置变化。 雅各布&…...

深蓝词库转换器:跨平台输入法词库一键迁移终极指南

深蓝词库转换器:跨平台输入法词库一键迁移终极指南 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 还在为更换输入法而烦恼吗?每次切换到新的…...

OpenClaw安全指南:千问3.5-35B-A3B-FP8本地化管控3大关键点

OpenClaw安全指南:千问3.5-35B-A3B-FP8本地化管控3大关键点 1. 为什么需要特别关注OpenClaw的安全管控? 去年夏天,我在调试一个自动整理照片的OpenClaw任务时,不小心让AI误删了整整一个季度的项目资料。那一刻我才真正意识到——…...

4个革命性的B站体验升级:Windows平台的UWP客户端解决方案

4个革命性的B站体验升级:Windows平台的UWP客户端解决方案 【免费下载链接】BiliBili-UWP BiliBili的UWP客户端,当然,是第三方的了 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBili-UWP 一、问题诊断:Windows用户的B…...

2026前端面经

2026前端面经1、前端怎么做到页面无刷新1、前端怎么做到页面无刷新 前端无刷新更新页面,核心就是不重新加载整个 HTML 页面,只局部更新数据和视图,这也是现代 Web 应用(SPA)的核心能力。 原生 AJAX (XMLHttpRequest)…...

5个核心概念理解上下文工程:从Prompt Engineering到Context Engineering的范式转移

5个核心概念理解上下文工程:从Prompt Engineering到Context Engineering的范式转移 【免费下载链接】Awesome-Context-Engineering 🔥 Comprehensive survey on Context Engineering: from prompt engineering to production-grade AI systems. hundred…...