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

Linux 信号量

Linux 信号量

    • 一、信号量基础概念
      • 1.1 同步机制的核心需求
      • 1.2 信号量的核心原理
      • 1.3 信号量类型对比
    • 二、实战代码解析
      • 2.1 共享内存与信号量结合示例
      • 2.2 信号量类实现要点
    • 三、关键实现细节分析
      • 3.1 初始化三步骤
      • 3.2 SEM_UNDO机制
      • 3.3 原子操作保证
    • 四、进阶应用场景
      • 4.1 生产者-消费者模型
      • 4.2 读写锁实现
    • 五、最佳实践建议
    • 六、常见问题排查
    • 七、现代替代方案

一、信号量基础概念

1.1 同步机制的核心需求

在多进程/多线程编程中,当多个执行单元需要访问共享资源时,必须引入同步机制来保证数据一致性。信号量(Semaphore)正是解决这一问题的经典方案。

1.2 信号量的核心原理

信号量本质上是一个计数器,通过两个原子操作实现进程同步:

  • P操作(wait):申请资源,计数器减1
  • V操作(post):释放资源,计数器加1

1.3 信号量类型对比

类型System V信号量POSIX信号量
初始化方式需要显式初始化可静态初始化
作用域系统级进程级
性能较高开销较低开销
功能复杂度支持信号量集合仅支持单个信号量

二、实战代码解析

2.1 共享内存与信号量结合示例

// 演示使用信号量给共享内存加锁
#include "_public.h"struct stgirl {int no;char name[51];
};int main(int argc, char* argv[]) {if (argc != 3) {cout << "Usage: ./test no name\n";return -1;}// 创建/获取共享内存int shmid = shmget(0x5005, sizeof(stgirl), 0640|IPC_CREAT);stgirl* ptr = (stgirl*)shmat(shmid, 0, 0);// 初始化信号量csemp mutex;mutex.init(0x5005);// 临界区保护cout << "申请加锁...\n";mutex.wait();// 操作共享数据cout << "原值: no=" << ptr->no << ", name=" << ptr->name << endl;ptr->no = atoi(argv[1]);strcpy(ptr->name, argv[2]);sleep(10); // 模拟耗时操作mutex.post();shmdt(ptr);return 0;
}

2.2 信号量类实现要点

class csemp {
public:bool init(key_t key, unsigned short value=1, short sem_flg=SEM_UNDO);bool wait(short sem_op=-1);bool post(short sem_op=1);// ...其他成员函数
private:int m_semid;short m_sem_flg;
};// 初始化流程图
graph TDA[开始] --> B{信号量是否存在?}B -- 存在 --> C[直接获取]B -- 不存在 --> D[创建新信号量]D --> E[设置初始值]E --> F[初始化完成]

三、关键实现细节分析

3.1 初始化三步骤

  1. 尝试获取现有信号量
  2. 创建新信号量(IPC_EXCL保证原子性)
  3. 设置初始值(仅创建者需要)

3.2 SEM_UNDO机制

  • 作用:防止进程异常终止导致的死锁
  • 实现方式:内核维护调整记录
  • 适用场景:建议用于互斥锁场景

3.3 原子操作保证

struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; // P操作
sem_b.sem_flg = SEM_UNDO;
semop(m_semid, &sem_b, 1);

四、进阶应用场景

4.1 生产者-消费者模型

// 初始化两个信号量
csemp empty(10); // 缓冲区空位
csemp full(0);   // 已填充数量// 生产者
empty.wait();
// 生产数据...
full.post();// 消费者
full.wait();
// 消费数据...
empty.post();

4.2 读写锁实现

csemp mutex(1);   // 互斥锁
csemp writeLock(1);// 写锁
int readers = 0;// 读锁定
mutex.wait();
readers++;
if (readers == 1) writeLock.wait();
mutex.post();// 读解锁
mutex.wait();
readers--;
if (readers == 0) writeLock.post();
mutex.post();// 写锁定
writeLock.wait();// 写解锁
writeLock.post();

五、最佳实践建议

  1. 命名规范

    • 使用ftok生成唯一key
    • 示例:key_t key = ftok("/tmp", 'A');
  2. 错误处理

    if (semop(...) == -1) {if (errno == EINTR) {// 处理信号中断}// 其他错误处理
    }
    
  3. 性能优化

    • 优先考虑POSIX信号量
    • 避免过度使用信号量集合
    • 设置合理的超时机制
  4. 调试技巧

    • 使用ipcs -s查看信号量状态
    • 通过semctl获取当前值

六、常见问题排查

  1. ENOSPC错误

    • 原因:系统信号量数量达到上限
    • 解决:sysctl -w kernel.sem="250 32000 100 128"
  2. EIDRM错误

    • 现象:信号量被意外删除
    • 预防:增加引用计数机制
  3. 死锁检测

    • 使用pstack分析进程堆栈
    • 借助valgrind工具链检测

七、现代替代方案

  1. 原子变量

    std::atomic<int> counter(0);
    counter.fetch_add(1, std::memory_order_relaxed);
    
  2. 文件锁

    int fd = open("lockfile", O_CREAT|O_RDWR, 0644);
    flock(fd, LOCK_EX);
    
  3. RCU机制

    • 适用读多写少场景
    • 无锁读取设计

信号量作为经典的进程同步工具,在系统级编程中仍具有重要地位。理解其底层机制并结合现代编程范式,能够帮助开发者构建更健壮的并发系统。在实际应用中,需要根据具体场景选择最合适的同步策略,平衡性能与安全性。

相关文章:

Linux 信号量

Linux 信号量 一、信号量基础概念1.1 同步机制的核心需求1.2 信号量的核心原理1.3 信号量类型对比 二、实战代码解析2.1 共享内存与信号量结合示例2.2 信号量类实现要点 三、关键实现细节分析3.1 初始化三步骤3.2 SEM_UNDO机制3.3 原子操作保证 四、进阶应用场景4.1 生产者-消费…...

Qt开发①Qt的概念+发展+优点+应用+使用

目录 1. Qt的概念和发展 1.1 Qt的概念 1.2 Qt 的发展史&#xff1a; 1.3 Qt 的版本 2. Qt 的优点和应用 2.1 Qt 的优点&#xff1a; 2.2 Qt 的应用场景 2.3 Qt 的应用案例 3. 搭建 Qt 开发环境 3.1 Qt 的开发工具 3.2 Qt SDK 的下载和安装 3.3 Qt 环境变量配置和使…...

向量库(Vector Database)

向量库 1. 向量库发展史 早期阶段&#xff08;2000s&#xff09; 基于关系型数据库的扩展&#xff08;如 PostgreSQL 的向量插件&#xff09;。简单相似度计算&#xff08;如欧氏距离、余弦相似度&#xff09;。 专用向量库的兴起&#xff08;2010s&#xff09; FAISS&#xf…...

torchsparse安装过程的问题

1、项目要求torchsparse githttps://github.com/mit-han-lab/torchsparse.gitv1.4.0 2、torch1.8.1cu111 nvcc--version&#xff1a;11.1 这个版本的cuda匹配的gcc、g经常是7.5。设置为7.5. &#xff08;这个gcc、g版本修改不一定&#xff0c;可以先进行后面的&#xff0c…...

【核心算法篇七】《DeepSeek异常检测:孤立森林与AutoEncoder对比》

大家好,今天我们来深入探讨一下《DeepSeek异常检测:孤立森林与AutoEncoder对比》这篇技术博客。我们将从核心内容、原理、应用场景等多个方面进行详细解析,力求让大家对这两种异常检测方法有一个全面而深入的理解。 一、引言 在数据科学和机器学习领域,异常检测(Anomaly…...

Win10环境使用零讯ZeroNews内网穿透实现Deepseek对外服务

Win10环境使用零讯ZeroNews内网穿透实现Deepseek对外服务 前言 之前笔者已经在Win10环境搭建好了Ollama、DeepSeek、Open WebUI、Dify等组件&#xff0c;成功实现了私有化部署及内网访问&#xff1a; https://lizhiyong.blog.csdn.net/article/details/145505686 https://l…...

CUDA 安装 一直卡在Installing Nsight Visual Studio Edition

最近在安装CUDA的时候&#xff0c;CUDA 安装 一直卡在Installing Nsight Visual Studio Edition&#xff0c;莫名的一直卡在安装进行中这儿&#xff0c;过很久都没进度&#xff0c;如图 后面重新下载了12.6的进行安装也是如此 无论是local还是network&#xff0c;都是这样。度…...

Softing线上研讨会 | 自研还是购买——用于自动化产品的工业以太网

| 线上研讨会时间&#xff1a;2025年1月27日 16:00~16:30 / 23:00~23:30 基于以太网的通信在工业自动化网络中的重要性日益增加。设备制造商正面临着一大挑战——如何快速、有效且经济地将工业以太网协议集成到其产品中。其中的关键问题包括&#xff1a;是否只需集成单一的工…...

STM32 定时器产生定周期方法

目录 背景 程序 第一步、使能PCLK1外设时钟​编辑 第二步、时基单元配置 第三步、配置NVIC&#xff08;设置定时中断优先级&#xff09;​编辑 第四步、使能溢出中断 第五步、使能定时器 第六步、填写中断处理函数&#xff08;ISR&#xff09; 背景 在单片机开发当中&…...

解锁机器学习核心算法 | 支持向量机:机器学习中的分类利刃

一、引言 在机器学习的庞大算法体系中&#xff0c;有十种算法被广泛认为是最具代表性和实用性的&#xff0c;它们犹如机器学习领域的 “十大神器”&#xff0c;各自发挥着独特的作用。这十大算法包括线性回归、逻辑回归、决策树、随机森林、K - 近邻算法、K - 平均算法、支持向…...

青少年编程与数学 02-009 Django 5 Web 编程 21课题、部署

青少年编程与数学 02-009 Django 5 Web 编程 21课题、部署 一、软件开发部署部署的主要内容部署的步骤部署的方式部署的环境 二、Django项目部署1. 准备工作2. 代码部署3. 配置Django项目4. Web服务器和应用服务器配置5. 安全和性能优化6. 监控和日志管理7. 测试和上线 三、在U…...

ARM系统源码编译OpenCV 4.10.0(包含opencv_contrib)

因项目部署在ARM系统上&#xff0c;需要编译一个arm版本的opencv-4.10.0&#xff08;带opencv_contrib&#xff09;版本。 若需要Linux系统下源码安装OpenCV&#xff0c;可参考&#xff1a;https://blog.csdn.net/qq_45445740/article/details/142770493?spm1001.2014.3001.55…...

cmake:定位Qt的ui文件

如题。在工程中&#xff0c;将h&#xff0c;cpp&#xff0c;ui文件放置到不同文件夹下&#xff0c;会存在cmake找不到ui文件&#xff0c;导致编译报错情况。 cmake通过指定文件路径&#xff0c;确保工程找到ui文件。 标识1&#xff1a;ui文件保存路径。 标识2&#xff1a;添加…...

(leetcode 1749 前缀和)1749. 任意子数组和的绝对值的最大值

核心题意 任意子数组和 的绝对值的最大值实际上是前缀和之间的差的最大值 建立前缀和数组 如果我们只考虑前缀和的最大值和最小值之差&#xff0c;那么就能够获得一个最大的子数组和的绝对值。因为任意一个子数组的和 prefix[j1] - prefix[i]&#xff0c;它的绝对值是最大当…...

下载安装运行测试开源vision-language-action(VLA)模型OpenVLA

1. 安装 项目官网OpenVLA 首先按照官网提示的以下代码&#xff0c;执行创建环境->安装最小依赖->git克隆项目等 # Create and activate conda environment conda create -n openvla python3.10 -y conda activate openvla# Install PyTorch. Below is a sample comma…...

【网络安全 | 漏洞挖掘】我如何通过Cookie Manipulation发现主域上的关键PII?

未经许可,不得转载。 文章目录 正文正文 在分析 Example.com 的认证机制时,我注意到一个特定的 cookie,USER_ID,包含了一个具有预测性的会话标识符,其格式为: USER_ID="VYCVCDs-TZBI:XXXX-random-data"其中,XXXX 是由四个大写字母组成的部分,我使用 Burp S…...

【操作系统】操作系统概述

操作系统概述 1.1 操作系统的概念1.1.1 操作系统定义——什么是OS&#xff1f;1.1.2 操作系统作用——OS有什么用&#xff1f;1.1.3 操作系统地位——计算机系统中&#xff0c;OS处于什么地位&#xff1f;1.1.4 为什么学操作系统&#xff1f; 1.2 操作系统的历史1.2.1 操作系统…...

SQL Server 运算符优先级

在 SQL Server 中&#xff0c;运算符的优先级决定了在没有使用括号明确指定计算顺序时&#xff0c;运算符的执行顺序。 运算符优先级列表 括号 () 一元运算符 &#xff08;正号&#xff09;-&#xff08;负号&#xff09;~&#xff08;按位取反&#xff09; 乘法、除法和取模…...

Python的顺序结构和循环结构

文章目录 一、条件语句&#xff08;1&#xff09;条件语句的定义&#xff08;2&#xff09;条件语句的语法&#xff08;a&#xff09;单分支 if&#xff08;b&#xff09;双分支 if-else&#xff08;c&#xff09;多分支 if-elif-elif-...-else &#xff08;3&#xff09;注意事…...

深入浅出TypedArray:网络数据处理、WebGPU与加密实战

JavaScript的TypedArray是现代Web开发中处理二进制数据的利器。本文将结合网络数据传输、WebGPU编程和简单加密算法三个实战场景&#xff0c;带你领略TypedArray的强大能力。 一、TypedArray基础认知 TypedArray家族包括Int8Array、Uint16Array、Float32Array等11种视图类型&a…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...