【Linux】学习记录_15_POSIX信号量

15 POSIX信号量

15.1 POSIX信号量基本概念

信号量(Semaphore)是一种实现进程/线程间通信的机制,可以实现进程/线程之间同步或临界资源的互斥访问, 常用于协助一组相互竞争的进程/线程来访问临界资源。在多进程/线程系统中, 各进程/线程之间需要同步或互斥实现临界资源的保护,信号量功能可以为用户提供这方面的支持。

在 POSIX标准中,信号量分两种:

  • 无名信号量,无名信号量一般用于进程/线程间同步或互斥,无名信号量则直接保存在内存中
  • 有名信号量,有名信号量一般用于进程间同步或互斥。 而有名信号量则要求创建一个文件

而且在不同进程/线程之间,为了争夺有限的系统资源(硬件或软件资源)会进入竞争状态,这就是进程/线程之间的互斥关系。 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权, 在任一时刻只能有一个执行进程/线程访问代码的临界区域。

临界区域是指执行数据更新的代码需要独占式地执行。 而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个进程/线程在访问它, 因此信号量是可以用来调协进程/线程对共享资源的访问的。进程/线程之间的互斥与同步关系存在的根源在于临界资源。 临界资源是在同一个时刻只允许有限个(通常只有一个)进程/线程可以访问(读)或修改(写)的资源, 通常包括硬件资源(处理器、内存、存储器以及其他外围设备等)和软件资源(共享代码段,共享结构和变量等)。

抽象的来讲,信号量中存在一个非负整数,所有获取它的进程/线程都会将该整数减一(获取它当然是为了使用资源), 当该整数值为零时,所有试图获取它的进程/线程都将处于阻塞状态。通常一个信号量的计数值用于对应有效的资源数, 表示剩下的可被占用的互斥资源数。其值的含义分两种情况:

  • 0:表示没有可用的信号量,进程/线程进入睡眠状态,直至信号量值大于 0。
  • 正值:表示有一个或多个可用信号量,进程/线程可使用该资源。进程/线程将信号量值减1。

对信号量的操作可以分为两个:

  • P 操作:如果有可用的资源(信号量值大于0),则占用一个资源(给信号量值减去一,进入临界区代码); 如果没有可用的资源(信号量值等于0),则阻塞,直到系统将资源分配给该进程/线程(进入等待队列, 一直等到资源轮到该进程/线程)。
  • V 操作:如果在该信号量的等待队列中有进程/线程在等待资源,则唤醒一个阻塞的进程/线程。如果没有进程/线程等待它, 则释放一个资源(给信号量值加一)

15.2 POSIX有名信号量

如果要在Linux中使用信号量同步,需要包含头文件 semaphore.h

有名信号量其实是一个文件,它的名字由类似 “sem.[信号量名字]” 这样的字符串组成,注意看文件名前面有 “sem.” , 它是一个特殊的信号量文件,在创建成功之后,系统会将其放置在 /dev/shm 路径下, 不同的进程间只要约定好一个相同的信号量文件名字,就可以访问到对应的有名信号量, 并且借助信号量来进行同步或者互斥操作,需要注意的是,有名信号量是一个文件,在进程退出之后它们并不会自动消失, 而需要手工删除并释放资源。

主要用到的函数:

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);
  • sem_open()函数用于打开/创建一个有名信号量,它的参数说明如下:
    • name:打开或者创建信号量的名字。
    • oflag:当指定的文件不存在时,可以指定 O_CREATE 或者 O_EXEL进行创建操作, 如果指定为0,后两个参数可省略,否则后面两个参数需要带上。
    • mode:数字表示的文件读写权限,如果信号量已经存在,本参数会被忽略。
    • value:信号量初始的值,这这个参数只有在新创建的时候才需要设置,如果信号量已经存在,本参数会被忽略。
    • 返回值:返回值是一个sem_t类型的指针,它指向已经创建/打开的信号量, 后续的函数都通过改信号量指针去访问对应的信号量。
  • sem_wait()函数是等待(获取)信号量,如果信号量的值大于0,将信号量的值减1,立即返回。如果信号量的值为0, 则进程/线程阻塞。相当于P操作。成功返回0,失败返回-1。
  • sem_trywait()函数也是等待信号量,如果指定信号量的计数器为0,那么直接返回EAGAIN错误,而不是阻塞等待。
  • sem_post()函数是释放信号量,让信号量的值加1,相当于V操作。成功返回0,失败返回-1。
  • sem_close()函数用于关闭一个信号量,这表示当前进程/线程取消对信号量的使用,它的作用仅在当前进程/线程, 其他进程/线程依然可以使用该信号量,同时当进程结束的时候,无论是正常退出还是信号中断退出的进程, 内核都会主动调用该函数去关闭进程使用的信号量,即使从此以后都没有其他进程/线程在使用这个信号量了, 内核也会维持这个信号量。
  • sem_unlink()函数就是主动删除一个信号量,直接删除指定名字的信号量文件。

15.3 POSIX无名信号量

无名信号量的操作与有名信号量差不多,但它不使用文件系统标识,直接存在程序运行的内存中, 不同进程之间不能访问,不能用于不同进程之间相互访问。同样的一个父进程初始化一个信号量, 然后fork其副本得到的是该信号量的副本,这两个信号量之间并不存在关系。

主要用到的函数:

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
  • sem_init():初始化信号量。
    • 其中sem是要初始化的信号量,不要对已初始化的信号量再做sem_init操作,会发生不可预知的问题。
    • pshared表示此信号量是在进程间共享还是线程间共享,由于目前Linux 还没有实现进程间共享无名信号量, 所以这个值只能够取0,表示这个信号量是当前进程的局部信号量。
    • value是信号量的初始值。
    • 返回值:成功返回0,失败返回-1。
  • sem_destroy():销毁信号量,其中sem是要销毁的信号量。只有用sem_init初始化的信号量才能用sem_destroy()函数销毁。 成功返回0,失败返回-1。
  • sem_wait()、sem_trywait()、sem_post()等函数与有名信号量的使用是一样的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1538.shtml

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

相关文章

Microchip 32位MCU CAN驱动图文教程-附源码

文章目录 创建一个新的32位MCU工程Microchip MCC Harmony配置界面说明在MCC下配置系统的时钟在MCC下配置所需要使用的模块配置调试打印模块配置CAN模块配置管脚功能修改系统堆栈大小生成代码 添加用户代码 创建一个新的32位MCU工程 确保电脑上已经安装最新的MPlab X IDE、XC32编…

ubuntu安装QEMU

qemu虚拟机的使用(一)——ubuntu20.4安装QEMU_ubuntu安装qemu-CSDN博客 遇到的问题: (1)本来使用git clone https://github.com/qemu/qemu.git fatal: 无法访问 https://github.com/qemu/qemu.git/:GnuTLS recv error (-110): …

使用 ADB 命令在 Android 设备上进行截屏

在 Android 开发和调试过程中,截取设备屏幕是一项非常有用的功能。ADB(Android Debug Bridge)是一个强大的工具,可以帮助我们与 Android 设备进行通信和调试。本文将介绍如何使用 ADB 命令在 Android 设备上进行截屏。 1. 准备工…

[阅读笔记18][CITING]LARGE LANGUAGE MODELS CREATE CURRICULUM FOR INSTRUCTION TUNING

这篇论文是23年10月提交到arxiv上的,也是用大模型蒸馏小模型的思路。 作者在这篇论文中提出了课程指令微调,大体流程如下图所示,教师模型给出一个问题,让学生模型回答一下,这时候学生回答大概率不够准确,这…

简化安卓操作:利用ADB命令返回主页、首页等操作

介绍: 在日常使用安卓设备时,经常需要返回到主页或者首页。虽然通过手动点击设备上的按钮可以轻松实现,但对于一些需要频繁进行此操作的场景,这种方式可能显得有些繁琐。幸运的是,利用ADB(Android Debug Br…

深度学习之图像分割从入门到精通——基于unet++实现细胞分割

模型 import torch from torch import nn__all__ [UNet, NestedUNet]class VGGBlock(nn.Module):def __init__(self, in_channels, middle_channels, out_channels):super().__init__()self.relu nn.ReLU(inplaceTrue)self.conv1 nn.Conv2d(in_channels, middle_channels, …

生态短讯 | Tapdata 与 TDengine 完成产品兼容性互认证,打造物联网实时数据生态

近月,深圳钛铂数据有限公司(以下简称钛铂数据)自主研发的实时数据平台(Tapdata Live Data Platform)与北京涛思数据科技有限公司(以下简称涛思数据)自主研发的大数据平台 TDengine,已…

【深度学习】Dropout、DropPath

一、Dropout 1. 概念 Dropout 在训练阶段会让当前层每个神经元以drop_prob( 0 ≤ drop_prob ≤ 1 0\leq\text{drop\_prob}\leq1 0≤drop_prob≤1)的概率失活并停止工作,效果如下图。 在测试阶段不会进行Dropout。由于不同批次、不同样本的神…

数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418)

数据库管理171期 2024-04-18 数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418)1 基本概念2 用处3 注意事项总结 数据库管理-第171期 Oracle是用这种方式确保读一致的(20240418) 作者:胖头鱼的鱼缸&#x…

MySQL中explain的用法

执行结果各字段的含义 EXPLAIN SQL语句 如: EXPLAIN SELECT * FROM test 执行结果: 列名描述id在一个大的查询语句中每个SELECT关键字都对应一个 唯一的idselect_typeSELECT关键字对应的那个查询的类型table表名partitions匹配的分区信息type针对单表…

P2P面试题

1)描述一下你的项目流程以及你在项目中的职责? 一个借款产品的发布,投资人购买,借款人还款的一个业务流程,我主要负责测注册,登录,投资理财这三个模块 2)你是怎么测试投资模块的&am…

前端nodead面试题

1.CSR和SSR分别是什么? CSR是客户端渲染,客户端访问网站时,服务器向客户端发送Html文档,让浏览器去渲染。其中像js,图片等还需要再次发请求。就是要啥给啥绝不多给。 缺点:不利于SEO,首次加载速度慢&…

HttpServlet,ServletContext,Listener它仨的故事

1.HttpServlet。 听起来是不是感觉像是个上古词汇,是不是没有阅读下去的兴趣了?Tomcat知道吧,它就是一个servlet容器,当用户向服务器发送一个HTTP请求时,Servlet容器(如Tomcat)会根据其配置找到…

【本地大模型】本地部署Llama3模型的极简教程

本地部署Llama3模型的极简教程 引言一、Llama3模型背景1、原理2、技术特点二、Ollama工具简介三、部署本地大模型(https://ollama.com/blog/llama3)1、安装Ollama四、运行Llama3模型五、Web UI的安装与配置1、安装open-webui2、启动Web UI3、解析本地文档六、整合使用1、Lang…

overflow(溢出)4个属性值,水平/垂直溢出,文字超出显示省略号的详解

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端工具”,可获取 Web 开发工具合…

解析 IP(IPv4)地址

IPv 4 地址 一、组成二、IPv4 的分类三、子网掩码四、特殊的地址五、私有 IP 地址六、全局 IP 地址七、私有 IP 地址和全局 IP 地址的关系八、广播地址九、网络地址十、IP 地址个数计算十一、查看电脑的 IP 地址(window)十二、手动设置电脑的 IP 地址 为…

面试十四、内存泄漏

1.内存溢出和内存泄漏是啥 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。 内存泄露 memo…

华为Pura 70系列,一种关于世界之美的可能

1874年,莫奈创作了《印象日出》的油画,在艺术界掀起了一场革命。当时的主流艺术,是追求细节写实,追求场面宏大的学院派。他们称莫奈等人是“印象派”,认为莫奈的画追求光影表达,追求描绘抽象的意境&#xf…

DRF: 序列化器、View、APIView、GenericAPIView、Mixin、ViewSet、ModelViewSet的源码解析

前言:还没有整理,后续有时间再整理,目前只是个人思路,文章较乱。 注意路径匹配的“/” 我们的url里面加了“/”,但是用apifox等非浏览器的工具发起请求时没有加“/”,而且还不是get请求,那么这…

天才简史——Sylvain Calinon

一、研究方向 learning from demonstration(LfD)领域的专家,机器人红宝书(Springer handbook of robotics)Robot programming by demonstration章节的合作者。主要研究兴趣包括: 机器人学习、最优控制、几…