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

【Linux】线程POSIX信号量

目录

1. 整体学习思维导图

2. 信号量的概念

3. 基本接口

4. 基于环形队列的生产者消费者模型(信号量)


1. 整体学习思维导图

2. 信号量的概念

POSIX信号量和SystemV信号量作用相同,都是用于同步操作,达到无冲突的访问共享资源目的。但

POSIX可以用于线程间同步。

POSIX信号量的本质是一个计数器,是对特定资源的预定机制!我们之前在进程通信时已经做了了解!

  • 多线程使用资源,有两种场景:

    • 将目标资源整体使用 【Mutex + 二元信号量】

    • 将目标资源划分为不同的"块",分批使用【信号量】 --> 电影院的观影座位售卖

  • 信号量一旦申请成功,就会保证该线程一定有块资源可以使用!(预定机制的体现)

  • 所有线程都需要看到sem信号量,因此信号量是临界资源。

  • PV操作需要是原子性的:

    • P:--

    • V: ++

3. 基本接口

1. 初始化信号量:sem_t sem; sem_init(&sem, 0, 1);&sem 是信号量指针。0 表示信号量用于线程间同步(1 表示进程间同步)。1 是信号量的初始值。2. P 操作:sem_wait(&sem);3. V 操作:sem_post(&sem);4. 销毁信号量:sem_destroy(&sem);
  • Sem.hpp 封装

#include <iostream>
#include <semaphore.h>
#include <pthread.h>namespace SemModule
{const int defaultvalue = 1;class Sem{public:Sem(unsigned int sem_value = defaultvalue){sem_init(&_sem, 0, sem_value);}void P(){int n = sem_wait(&_sem); // 原子的(void)n;}void V(){int n = sem_post(&_sem); // 原子的}~Sem(){sem_destroy(&_sem);}private:sem_t _sem;};
}

4. 基于环形队列的生产者消费者模型(信号量)

 

  • 实现单生产者/单消费者模型

    • P C --> p与c之间互斥和同步关系由信号量维持

  • 实现多生产者/多消费者模型

    • PP CC --> pp/cc之间的互斥关系需要维持 --> Mutex加锁 Enqueue/Pop

    • 因此我们需要两边锁,一把锁解决pp,一把锁解决cc

问题:先申请信号量,还是先加锁?

应该先申请信号量,有了信号量说明该对象将执行对应的Enqueue/Pop操作,再让有了信号量的对象竞争锁访问临界资源,这样排除了没有对应信号量执行操作的对象。如果先加锁,会导致拥有信号量的对象想要访问临界资源时的锁被没有信号量不需要执行操作的对象拿到了锁,从而造成死锁问题。

  1. 信号量筛选有效线程:只有持有信号量的线程才有资格竞争锁。

  2. 锁保证操作原子性:避免多个线程同时修改队列。

  3. 避免死锁:防止无效线程占用锁导致资源饥饿。

  • 代码实现:

#pragma once#include <iostream>
#include <vector>
#include "Sem.hpp"
#include "Mutex.hpp"static const int gcap = 5; // for debugusing namespace SemModule;
using namespace MutexModule;template <typename T>
class RingQueue
{
public:RingQueue(int cap = gcap): _cap(cap),_rq(cap),_blank_sem(cap),_p_step(0),_data_sem(0),_c_step(0){}void Equeue(const T &in){// 生产者// 1. 申请信号量,空位置信号量_blank_sem.P();{LockGuard lockguard(_pmutex);// 2. 生产_rq[_p_step] = in;// 3. 更新下标++_p_step;// 4. 维持环形特性_p_step %= _cap;}_data_sem.V();}void Pop(T *out){// 消费者// 1. 申请信号量,数据信号量_data_sem.P();{LockGuard lockguard(_cmutex);// 2. 消费*out = _rq[_c_step];// 3. 更新下标++_c_step;// 4. 维持环形特性_c_step %= _cap;}_blank_sem.V();}private:std::vector<T> _rq;int _cap;// 生产者Sem _blank_sem; // 空位置int _p_step;// 消费者Sem _data_sem; // 数据int _c_step;// 维护多生产,多消费, 2把锁Mutex _cmutex;Mutex _pmutex;
};
http://www.xdnf.cn/news/379657.html

相关文章:

  • JDBC工具类
  • c#建筑行业财务流水账系统软件可上传记账凭证财务管理系统签核功能
  • 代码随想录算法训练营第三十七天
  • win10-启动django项目时报错
  • ndk.symlinkdir - 在 Android Studio 3.5 及更高版本中,创建指向 NDK 的符号链接
  • 关于数据库查询速度优化
  • vue3使用tailwindcss报错问题
  • C.循环函数基础
  • 远程调试---在电脑上devtools调试运行在手机上的应用
  • PyTorch API 3 - mps、xpu、backends、导出
  • 6.秒杀优化
  • 更换内存条会影响电脑的IP地址吗?——全面解析
  • A2A大模型协议及Java示例
  • 以影像为笔,劳润智在世界舞台上书写艺术之路
  • 不同句子切割(文本分段 / chunking)工具或库 各自采用的策略和目标对比和分析
  • OLE(对象链接与嵌入)剪贴板内容插入到 CAD 图形中——CAD c# 二次开发
  • 非阻塞式IO-Java NIO
  • TCP Socket编程
  • 分布式锁原理
  • Linux 信号终篇(总结)
  • OpenAI API JSON 格式指南与json_repair错误修复
  • 深入理解卷积神经网络的输入层:数据的起点与预处理核心
  • [Pandas]数据处理
  • MySQL 从入门到精通(六):视图全面详解 —— 虚拟表的灵活运用
  • PyTorch量化感知训练技术:模型压缩与高精度边缘部署实践
  • TDengine 在智能制造中的核心价值
  • 工控新宠| 触想Z系列工控机C款发布,方寸机身,智控万千
  • OSPF综合实验实验报告
  • 深度学习篇---MediaPipe 及其人体姿态估计模型详解
  • 广东省省考备考(第七天5.10)—言语:片段阅读(每日一练)