linux进程间通信之信号量

         注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物。

摘要

        本文旨在深入探讨Linux进程间通信中的信号量机制,包括其工作原理、系统调用接口以及实际应用场景。通过理论分析和示例代码的解读,本文将帮助读者更好地理解信号量在多进程环境中的作用和应用。

一.信号量的简介

        在Linux操作系统中,进程间通信(IPC)是一种非常重要的技术,它允许不同的进程之间共享信息和数据。信号量是进程间通信的一种方式,它用于控制多个进程对共享资源的访问。

        信号量是一个计数器,它可以被视为一个在进程之间共享的变量。通过使用信号量,一个进程可以等待一个资源被释放,或者通知其他进程一个资源已经可用。      

        举个例子,就是两个进程共享信号量 sv ,一旦其中一个进程执行了 P(sv) 操作,它将得到信号量,并可 以进入临界区,使 sv 1 。而第二个进程将被阻止进入临界区,因为当它试图执行 P(sv) 时, sv 0 ,它会 被挂起以等待第一个进程离开临界区域并执行 V(sv) 释放信号量,这时第二个进程就可以恢复执行。

二.信号量工作原理与步骤

        信号量是一个计数器,可以看作是在进程之间共享的变量。它主要用于解决多个进程对共享资源的访问冲突问题。当一个进程需要访问共享资源时,它会首先检查信号量的值。如果信号量的值为正,则该进程可以继续执行;如果信号量的值为0,则该进程会被阻塞,直到其他进程释放资源并增加信号量的值。

使用 System V 信号灯的步骤如下:
        1. 使用 semget() 创建或打开一个信号灯集。
        2. 使用 semctl() 初始化信号灯集,。
        3. 使用 semop() 操作信号灯值,即进行 P/V 操作。
        P 操作:申请资源,申清完后信号灯值 -1
        V 操作:释放资源,释放资源后信号灯值 +1

三.系统调用接口

        信号量是一个特殊的变量,程序对其访问都是原子操作,且只允许对它进行等待(即 P(信号变量))和发送(即 V(信号变量))信息操作。我们通常通过信号来解决多个进程对同一资源的访问竞争的问题,使在任一 时刻只能有一个执行线程访问代码的临界区域,也可以说它是协调进程间的对同一资源的访问权,也就是用于同步进程的。

在Linux中,使用信号量需要进行一系列系统调用。以下是几个常用的系统调用接口:

1.sem_init

  用于初始化一个信号量。它接受三个参数:信号量对象的键值、信号量的初始值和共享内存的权限标志。

2.semop

  用于对信号量进行操作,包括锁定和解锁。它接受三个参数:信号量对象的键值、指向sembuf结构体的指针和操作的个数。

3.sem_wait

  用于锁定信号量。它将信号量的值减1,如果信号量的值为负,则该进程会被阻塞。

4.sem_post

  用于解锁信号量。它将信号量的值加1,如果信号量的值为正,则继续等待的进程将被唤醒。

5.sem_destroy

  用于销毁一个信号量。它接受一个参数:信号量对象的键值。

四.实验代码

         指定哪个进程运行,可以使用进程间通信的知识,或者使用信号量,这里以使用信号量为例:

#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <sys/ipc.h>  
#include <sys/sem.h>  #define SEMKEY 123456 // 信号量键  int main() {  int semid; // 信号量标识符  struct sembuf sembuf_lock = {0, -1, SEM_UNDO}; // 用于锁定信号量的结构体  struct sembuf sembuf_unlock = {0, 1, SEM_UNDO}; // 用于解锁信号量的结构体  // 创建信号量,初始值为1  if ((semid = sem_init(SEMKEY, 0, 1)) < 0) {  perror("sem_init");  exit(EXIT_FAILURE);  }  // 创建子进程  pid_t pid = fork();  if (pid < 0) {  perror("fork");  exit(EXIT_FAILURE);  } else if (pid == 0) { // 子进程  printf("Child process is running.\n");  // 锁定信号量,等待资源可用if (semop(semid, &sembuf_lock, 1) < 0) {  perror("semop");  exit(EXIT_FAILURE);  }  printf("Child process got the resource.\n");  // 使用资源,模拟执行一段时间  sleep(2);  // 解锁信号量,释放资源  if (semop(semid, &sembuf_unlock, 1) < 0) {  perror("semop");  exit(EXIT_FAILURE);  }  printf("Child process finished using the resource.\n");  } else { // 父进程  printf("Parent process is running.\n");  // 等待子进程锁定信号量  sleep(1);  // 锁定信号量,尝试获取资源,等待子进程释放资源  if (semop(semid, &sembuf_lock, 1) < 0) {  perror("semop");  exit(EXIT_FAILURE);  }  printf("Parent process got the resource.\n");  // 使用资源,模拟执行一段时间  sleep(2);  // 解锁信号量,释放资源  if (semop(semid, &sembuf_unlock, 1) < 0) {  perror("semop");  exit(EXIT_FAILURE);  }  printf("Parent process finished using the resource.\n");  }  // 销毁信号量  if (sem_destroy(semid) < 0) {  perror("sem_destroy");  exit(EXIT_FAILURE);  }  return 0;  
}

五、结论

         通过本文对Linux进程间通信之信号量的深入剖析及示例代码的讲解,可以得出以下结论:信号量是一种有效的进程间同步和协调机制,能够解决多个进程对共享资源的访问冲突问题。通过系统调用接口,我们可以创建、操作和销毁信号量。在示例代码中,我们展示了如何使用信号量实现进程间的同步和协调,确保在同一时间只有一个进程使用共享资源,从而避免了竞争条件和数据不一致的问题。总之,信号量是Linux进程间通信中不可或缺的一部分,对于多进程应用程序的开发具有重要意义。

 

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

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

相关文章

开发者分享 | Ascend C算子开发及单算子调用

本文分享自《AscendC算子开发及单算子调用》&#xff0c;作者&#xff1a;goldpancake。 笔者在阅读Ascend C官方文档的过程中发现&#xff0c;对于初学者来说&#xff0c;尤其是第一次接触异构编程思想的初学者&#xff0c;有部分内容是无需特别关注的&#xff0c;例如算子工…

linux systemd start stop enable disable命令区别

一、systemd 的服务在三个文件件下 /lib/systemd/system /etc/systemd/system /usr/lib/systemd/system 终于明白这几个命令的区别 systemd star systemd stop systemd enable systemd disable 二、 1、用ssh服务为例&#xff0c;&#xff0c;ssh是客户端&#xff0c;远程ss…

线性表--顺序表-1

文章目录 主要内容一.基础练习题1.从顺序表中删除具有最小值的元素&#xff08;假设唯一&#xff09;并由函数返回被删元素的值。空出位置由最后元素填补&#xff0c;若顺序表为空&#xff0c;则显示出错信息并退出运行。代码如下&#xff08;示例&#xff09;: 2.设计一个高效…

持续集成交付CICD:Jenkins通过API触发流水线

目录 一、理论 1.HTTP请求 2.调用接口的方法 3.HTTP常见错误码 二、实验 1.Jenkins通过API触发流水线 三、问题 1.如何拿到上一次jenkinsfile文件进行自动触发流水线 一、理论 1.HTTP请求 &#xff08;1&#xff09;概念 HTTP超文本传输协议&#xff0c;是确保服务器…

JS特效:跟随鼠标移动的小飞机

前端网页中&#xff0c;用JS实现鼠标移动时&#xff0c;页面中的小飞机向着鼠标移动。 效果 源码 <!DOCTYPE html> <html><head><style>*{margin: 0;padding: 0;}body{height: 100vh;background: linear-gradient(200deg,#005bea,#00c6fb);}#plane{…

[C/C++]数据结构 链表(单向链表,双向链表)

前言: 上一文中我们介绍了顺序表的特点及实现,但是顺序表由于每次扩容都是呈二倍增长(扩容大小是自己定义的),可能会造成空间的大量浪费,但是链表却可以解决这个问题. 概念及结构: 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接…

HC-SR501传感器制作一个报警系统

接线图&#xff1a; 引脚连接&#xff1a; 1. 将 PIR 信号引脚连接到 arduino 数字 引脚 13。 2. 将 PIR V 引脚连接 到 arduino 5v 引脚。 3. 将 PIR GND 引脚连接到 arduino GND 引脚。 4. 将arduino数字 引脚12连接 到220欧姆电阻&#xff0c;并将该电阻连接到 LED V …

Java Swing猜单词游戏

内容要求 1&#xff09; 本次程序设计是专门针对 Java 课程的,要求使用 Java 语言进行具有一定代码量的程序开发。程序的设计要结合一定的算法&#xff0c;在进行代码编写前要能够设计好自己的算法。 2&#xff09;本次程序设计涉及到 Java 的基本语法&#xff0c;即课堂上所…

提升工作效率,打造精细思维——OmniOutliner 5 Pro for Mac

在当今快节奏的工作环境中&#xff0c;如何高效地组织和管理我们的思维和任务成为了关键。而OmniOutliner 5 Pro for Mac正是为此而生的一款强大工具。无论你是专业写作者、项目经理还是学生&#xff0c;OmniOutliner 5 Pro for Mac都能帮助你提升工作效率&#xff0c;打造精细…

Fibonacci 数列与黄金分割

mapp[1 for item in range(30)] for item in range(3,30):mapp[item]mapp[item-1]mapp[item-2]pass numint(input()) if num>19:print("0.61803399")pass else:anss float((mapp[num]*1.0) / (mapp[num 1]*1.0))print(format(anss,.8f))进行短程的打表就可以看出…

实用篇-ES-DSL查询文档

数据的存储不是目的&#xff0c;我们希望从海量的酒店数据中检索出需要的信息&#xff0c;这就是ES的搜索功能 官方文档: https://elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html#query-dsl。DSL是用来查询文档的 Elasticsearch提供了基于JSON的DSL来定…

将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出

要将给定的表达式树转换为等价的中缀表达式&#xff0c;可以通过遍历表达式树的方式来实现。以下是一个以递归方式实现的示例代码&#xff1a; class Node:def __init__(self, value):self.value valueself.left Noneself.right Nonedef convert_to_infix_expression(root)…

阿里云ESSD云盘、高效云盘和SSD云盘介绍和IOPS性能参数表

阿里云服务器系统盘或数据盘支持多种云盘类型&#xff0c;如高效云盘、ESSD Entry云盘、SSD云盘、ESSD云盘、ESSD PL-X云盘及ESSD AutoPL云盘等&#xff0c;阿里云服务器网aliyunfuwuqi.com详细介绍不同云盘说明及单盘容量、最大/最小IOPS、最大/最小吞吐量、单路随机写平均时延…

SpringBoot-AOP-基础到进阶

SpringBoot-AOP AOP基础 学习完spring的事务管理之后&#xff0c;接下来我们进入到AOP的学习。 AOP也是spring框架的第二大核心&#xff0c;我们先来学习AOP的基础。 在AOP基础这个阶段&#xff0c;我们首先介绍一下什么是AOP&#xff0c;再通过一个快速入门程序&#xff0c…

【我和Python算法的初相遇】——体验递归的可视化篇

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:PYTHON数据结构与算法学习系列专栏&#x1f4ab;"没有罗马,那就自己创造罗马~" 目录 递归的起源 什么是递归? 利用递归解决列表求和问题 递归三定律 递归应用-整数转换为任意进制数 递归可视化 画…

Docker安装MinIO遇到的问题汇总——持续更新中

文章目录 Docker安装MinIO遇到的坑前言问题1&#xff1a;执行docker run报错Error response from daemon问题2&#xff1a;启动MinIO容器浏览器无法访问问题3&#xff1a;上传文件报错InvalidResponseException问题4&#xff1a;上传文件报错Connection refused最终的启动指令问…

Jmeter 吞吐量Per User作用

第一点&#xff1a;Per User仅在Total Execution时生效 第二点&#xff1a;Per User 选中后 聚合报告中将统计的的样本数将变成线程组配置的线程数*吞吐量控制器配置的执行样本数量&#xff08;前提是线程组配置执行接口的次数线程数*循环数 大于吞吐量控制器配置的执行样本数…

gittee启动器

前言 很多小伙伴反馈不是使用gitee&#xff0c;不会寻找好的项目&#xff0c;在拿到一个项目不知道从哪里入手。 鼠鼠我呀就是宠粉&#xff0c;中嘞&#xff0c;老乡。整&#xff01;&#xff01;&#xff01; git的基本指令 在使用gitee的时候呢&#xff0c;我们只需要记住…

Adversarially Robust Neural Architecture Search for Graph Neural Networks

Adversarially Robust Neural Architecture Search for Graph Neural Networks----《面向图神经网络的对抗鲁棒神经架构搜索》 摘要 图神经网络&#xff08;GNN&#xff09;在关系数据建模方面取得了巨大成功。尽管如此&#xff0c;它们仍然容易受到对抗性攻击&#xff0c;这对…

力扣周赛372 模拟 思维 位运算 java

100131. 使三个字符串相等 ⭐ AC code class Solution {public int findMinimumOperations(String s1, String s2, String s3) {int len1 s1.length();int len2 s2.length();int len3 s3.length();int n Math.min(len1,len2);n Math.min(n,len3);int i 0;while(i < n…