【Linux】线程POSIX信号量

news2025/5/11 20:58:04

目录

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 debug

using 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.coloradmin.cn/o/2373419.html

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

相关文章

MySQL事务和JDBC中的事务操作

一、什么是事务 事务是数据库操作的最小逻辑单元&#xff0c;具有"全有或全无"的特性。以银行转账为例&#xff1a; 典型场景&#xff1a; 从A账户扣除1000元 向B账户增加1000元 这两个操作必须作为一个整体执行&#xff0c;要么全部成功&#xff0c;要么全部失败…

每日脚本学习5.10 - XOR脚本

xor运算的简介 异或就是对于二进制的数据可以 进行同0异1 简单的演示 &#xff1a; 结果是 这个就是异或 异或的作用 1、比较两数是否相等 2、可以进行加密 加密就是需要key 明文 :0b010110 key : 0b1010001 这个时候就能进行加密 明文 ^ key密文 还有这个加密比…

【编译原理】总结

核心 闭包&#xff0c;正则闭包 产生式&#xff08;规则&#xff09; 文法 G[S](&#xff0c;&#xff0c;P&#xff0c;S) 一组规则的集合 &#xff1a;非终结符 &#xff1a;终结符 P&#xff1a;产生式 S&#xff1a;开始符号 推导 归约 规范&#xff08;最右&#xff…

docker创建一个centOS容器安装软件(以宝塔为例)的详细步骤

备忘&#xff1a;后续偶尔忘记了docker虚拟机与宿主机的端口映射关系&#xff0c;来这里查看即可&#xff1a; docker run -d \ --name baota \ --privilegedtrue \ -p 8888:8888 \ -p 8880:80 \ -p 8443:443 \ -p 8820:20 \ -p 8821:21 \ -v /home/www:/www/wwwroot \ centos…

OpenVLA:开源的视觉-语言-动作模型

1. 简介 让我们先来介绍一下什么是OpenVLA&#xff0c;在这里&#xff1a; https://openvla.github.io/ 可以看到他们的论文、数据、模型。 OpenVLA 是一个拥有 70亿参数的开源 **视觉-语言-动作&#xff08;VLA&#xff09;**模型。它是在 Open X-Embodiment 数据集 中的 97万…

Matlab/Simulink的一些功能用法笔记(4)

水一篇帖子 01--MATLAB工作区的保护眼睛颜色设置 默认的工作区颜色为白色 在网上可以搜索一些保护眼睛的RGB颜色参数设置 在MATLAB中按如下设置&#xff1a; ①点击预设 ②点击颜色&#xff0c;点击背景色的三角标符号 ③点击更多颜色&#xff0c;找到RGB选项 ④填写颜色参数…

Elasticsearch:我们如何在全球范围内实现支付基础设施的现代化?

作者&#xff1a;来自 Elastic Kelly Manrique SWIFT 和 Elastic 如何应对基础设施复杂性、误报问题以及日益增长的合规要求。 金融服务公司在全球范围内管理实时支付方面面临前所未有的挑战。SWIFT&#xff08;Society for Worldwide Interbank Financial Telecommunication -…

matlab介绍while函数

MATLAB 中的 while 语句介绍 在 MATLAB 中&#xff0c;while 语句是一种循环结构&#xff0c;用于在满足特定条件时反复执行一段代码块。与 for 循环不同&#xff0c;while 循环的执行次数是动态的&#xff0c;取决于循环条件是否为真。 语法 while condition% 循环体代码 e…

如何解决 PowerShell 显示 “此系统上禁用了脚本运行” 的问题

在 Windows 11 或 10 的 PowerShell 中运行脚本时,你可能会遇到一个错误,提示系统上禁用了脚本运行。这是一种安全功能,而不是系统问题,旨在防止可能有害的脚本自动运行。然而,如果你需要运行脚本来完成某些任务,或者你在系统上做了软件开发或测试的环境,那么你需要在 P…

深入浅出之STL源码分析4_类模版

1.引言 我在上面的文章中讲解了vector的基本操作&#xff0c;然后提出了几个问题。 STL之vector基本操作-CSDN博客 1.刚才我提到了我的编译器版本是g 11.4.0&#xff0c;而我们要讲解的是STL&#xff08;标准模板库&#xff09;&#xff0c;那么二者之间的关系是什么&#x…

初学者入门指南:什么是网络拓扑结构?

初学者入门指南&#xff1a;什么是网络拓扑结构&#xff1f; 在构建或学习计算机网络时&#xff0c;一个绕不开的核心概念便是“网络拓扑结构”&#xff08;Network Topology&#xff09;。它决定了网络中各个设备如何连接、通信以及如何扩展。理解网络拓扑不仅有助于我们更清…

Satori:元动作 + 内建搜索机制,让大模型实现超级推理能力

Satori&#xff1a;元动作 内建搜索机制&#xff0c;让大模型实现超级推理能力 论文大纲一、背景&#xff1a;LLM 推理增强的三类方法1. 基于大规模监督微调&#xff08;SFT&#xff09;的推理增强2. 借助外部机制在推理时进行搜索 (RLHF / 多模型 / 工具)3. 现有局限性总结 二…

SDC命令详解:使用all_outputs命令进行查询

相关阅读 SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html all_outputs命令用于创建一个输出端口对象集合&#xff0c;关于设计对象和集合的更详细介绍&#xff0c;可以参考下面的博客。 Synopsys&#xff1a;设计对象https://chenzhang.blog.csdn…

printf调试时候正常,运行时打印不出来

问题是在添加了 printf 功能后&#xff0c;程序独立运行时无法正常打印输出&#xff0c;而调试模式下正常。这表明问题可能与 printf 的重定向实现、标准库配置、或编译器相关设置有关。 解决&#xff1a; 原来是使用 Keil/IAR&#xff0c;printf可能需要启用 MicroLIB 或正确…

解决 TimeoutError: [WinError 10060] 在 FramePack项目中连接 Hugging Face 超时的问题

#工作记录 以下是针对 TimeoutError: [WinError 10060] 的完整排查方案&#xff0c;适用于 FramePack项目中。 &#xff08;一般该错误的发生原因请重点排查Hugging Face模型仓库受限需要登录的情形&#xff09; FramePack项目参考资料 FramePack部署&#xff08;从PyCharm解…

分布式-Redis分布式锁

Redis实现分布式锁优点 &#xff08;1&#xff09;Redis有很高的性能&#xff1b; &#xff08;2&#xff09;Redis命令对此支持较好&#xff0c;实现起来比较方便 实现思路 &#xff08;1&#xff09;获取锁的时候&#xff0c;使用setnx加锁&#xff0c;并使用expire命令为锁…

UniRepLknet助力YOLOv8:高效特征提取与目标检测性能优化

文章目录 一、引言二、UniRepLknet 的框架原理&#xff08;一&#xff09;架构概述&#xff08;二&#xff09;架构优势 三、UniRepLknet 在 YOLOv8 中的集成&#xff08;一&#xff09;集成方法&#xff08;二&#xff09;代码实例 四、实验与对比&#xff08;一&#xff09;对…

自研时序大模型讲解(4月29日)直播回顾

4 月 29 日&#xff0c;清华团队揭秘&#xff1a;时序大模型如何让数据“活”起来线上直播圆满结束。清华大学软件学院博士生&#xff0c;IoTDB 原生机器学习引擎 AINode 研发同学刘雍在线上面向数千人次的时序数据分析人员与 AI 大模型行业关注者&#xff0c;就时序大模型的发…

k8s之ingress解释以及k8s创建业务的流程定义

matchLabels ingress Ingress 是反向代理规则&#xff0c;用来规定 HTTP/S 请求应该被转发到哪个 Service 上&#xff0c;比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上。 Ingress Controller 就是一个反向代理程序&#xff0c;它负责解析 Ingress 的反向…

从0开始学习大模型--Day05--理解prompt工程

提示词工程原理 N-gram&#xff1a;通过统计&#xff0c;计算N个词共同出现的概率&#xff0c;从而预测下一个词是什么。 深度学习模型&#xff1a;有多层神经网络组成&#xff0c;可以自动从数据中学习特征&#xff0c;让模型通过不断地自我学习不断成长&#xff0c;直到模型…