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

linux进程间通讯--信号量

1.认识信号量

        方便理解:信号量就是一个计数器。当它大于0能用,小于等于0,用不了,这个值自己给。

2.特点:

  1. 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。
  2. 信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。(P操作:拿锁。V操作:放回锁)
  3. 每次对信号量的 PV 操作不仅限于对信号量值加 1 或 减1 ,而且可以加加减任意正整数。
  4. 支持信号量组

3.有关api:

#include <sys/sem.h>//1.创建或获取一个信号量组:若成功返回信号量级ID,失败返回-1
int semget(key_t key, int num_sems, int sem_flags);//2.对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops);//3.控制信号量的相关信息
int semctl(int semid, int sem_num, int cmd, ...);

1.semget

功能:创建一个新的信号量或获取一个已经存在的信号量的键值。

返回值:成功返回信号量的标识码ID。失败返回-1;

参数:

key  为整型值,用户可以自己设定。有两种情况:

1.       键值是IPC_PRIVATE,该值通常为0,意思就是创建一个仅能被进程进程给我的信号量。

2.       键值不是IPC_PRIVATE,我们可以指定键值,例如1234;也可以一个ftok()函数来取得一个唯一的键值。

sems 表示初始化信号量的个数。比如我们要创建一个信号量,则该值为1.,创建2个就是2。

flags  :信号量的创建方式或权限。有IPC_CREAT,IPC_EXCL。

IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。

IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。

2.semop

//2.对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops);

该函数的主要作用是执行对一个或多个信号量的原子操作,包括P操作(sem减1)和V操作(sem加1),以实现进程间的同步与互斥。

其中,参数semid为信号量集的标识符;参数sops指向进行操作的结构体数组的首地址;参数nsops指出将要进行操作的信号的个数。

需要注意的是,信号量的值只能通过PV操作来改变。当信号量的值大于0时,表示当前有可用资源,进程可以继续执行;若信号量的值小于等于0,则表示无可用资源,进程需要暂停等待。

另外,semop函数调用成功返回0,失败返回-1。因此在使用该函数时,需要进行错误检查以确保操作的正确性。

具体参数解释:

  _semid : 信号量的标识码。也就是semget()的返回值。

 _sembuf是一个指向结构体数组的指针。

1 struct sembuf 
2 {
3     short sem_num; // 信号量组中对应的序号,0~sem_nums-1
4     short sem_op;  // 信号量值在一次操作中的改变量
5     short sem_flg; // IPC_NOWAIT, SEM_UNDO
6 }

sembuf解释:

1.em_num:  操作信号在信号集中的编号。第一个信号的编号为0;

2.sem_op : 如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。

3.semflg

IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。

IPC_UNDO //程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。

_nsops:操作结构的数量,恒大于或等于1。

//3.控制信号量的相关信息
int semctl(int semid, int sem_num, int cmd, ...);

3.semctl

  1. semid:表示要操作的信号量集的标识符,通常由 semget() 函数返回。
  2. semnum:表示要操作的信号量的索引号,这里设置为 0,表示对第一个信号量进行操作。
  3. cmd    命令,表示要进行的操作

       下面列出的这些命令来源于百度!

        参数cmd中可以使用的命令如下:

  •         IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
  •         IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
  •         IPC_RMID将信号量集从内存中删除
  •         GETALL用于读取信号量集中的所有信号量的值。
  •         GETNCNT返回正在等待资源的进程数目。
  •         GETPID返回最后一个执行semop操作的进程的PID。
  •         GETVAL返回信号量集中的一个单个的信号量的值。
  •         GETZCNT返回这在等待完全空闲的资源的进程数目。
  •         SETALL设置信号量集中的所有的信号量的值。
  •         SETVAL设置信号量集中的一个单独的信号量的值。
    通常为标黄的命令

如果有第四个参数,它通常是一个union semum结构,定义如下:

union semun {int val;          // 用于SETVAL命令,表示要设置的信号量的值。struct semid_ds *buf; // 用于IPC_STAT、IPC_SET命令,指向一个semid_ds结构体的指针。unsigned short *array; // 用于GETALL、SETALL命令,指向一个无符号短整型数组的指针。struct seminfo *__buf; // 用于IPC_INFO命令,指向一个seminfo结构体的指针(Linux-specific)。
};

前两个参数与前面一个函数中的一样,command通常是下面两个值中的其中一个
SETVAL:用来把信号量初始化为一个已知的值。这个值通过union semun中的val成员设置,其作用是在信号量第一次使用前对它进行设置。

IPC_RMID:用于删除一个已经无需继续使用的信号量标识符。

4.代码例子

使用信号量实现父子进程先后进行。

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdlib.h>/*
//1.创建或获取一个信号量组:若成功返回信号量级ID,失败返回-1
int semget(key_t key, int num_sems, int sem_flags);//2.对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1
int semop(int semid, struct sembuf semoparray[], size_t numops);//3.控制信号量的相关信息
int semctl(int semid, int sem_num, int cmd, ...);*/// union for semctl to initialize
union semun {int val;          // 用于SETVAL命令,表示要设置的信号量的值。struct semid_ds *buf; // 用于IPC_STAT、IPC_SET命令,指向一个semid_ds结构体的指针。unsigned short *array; // 用于GETALL、SETALL命令,指向一个无符号短整型数组的指针。struct seminfo *__buf; // 用于IPC_INFO命令,指向一个seminfo结构体的指针(Linux-specific)。
};//initialize sem to 0int init_sem(int sem_id,int value){union semun tmp;tmp.val = value;if(semctl(sem_id,0,SETVAL,tmp)==-1){perror("init sem erro");return -1;}return 0;
}//p operate
// if sem == 1,get message to sem =-1
//if sem == 0, process waitint sem_p(int sem_id){struct sembuf pbuf;pbuf.sem_num  = 0;pbuf.sem_op   = -1;pbuf.sem_flg  = SEM_UNDO;if(semop(sem_id,&pbuf,1) == -1){perror("p operate error");return -1;}return 0;
}//v operate
//sem >1 operateint sem_v(int sem_id){struct sembuf vbuf;vbuf.sem_num  = 0;vbuf.sem_op   = 1;//v operatevbuf.sem_flg  = SEM_UNDO;if(semop(sem_id,&vbuf,1) == -1){perror("v operate error");return -1;}return 0;
}//delete semint del_sem(int sem_id){union semun tmp;if(semctl(sem_id,0,IPC_RMID) == -1){perror("delete sem error");return -1;}return 0;
}int main()
{int  sem_id;key_t key;pid_t pid;//get key numif((key = ftok(".",11))<0){perror("semget error");exit(-1);}//build sem only 1if(sem_id = semget(key,1,IPC_CREAT|0700)==-1){perror("semget error");exit(-1);}//initilizeinit_sem(sem_id,0);//father&child processif((pid = fork())== -1){perror("fork errror");exit(-1);}else if(pid == 0){   //child processsleep(1);printf("process from child pid :%d\n",getpid());sem_v(sem_id);//release resource &put tne lock}else {  //father processsem_p(sem_id);printf("father process pid:%d\n",getpid());sem_v(sem_id);del_sem(sem_id);}return 0;
}

突然意识到结构体和联合体是不同的,请看文章:

相关文章:

linux进程间通讯--信号量

1.认识信号量 方便理解&#xff1a;信号量就是一个计数器。当它大于0能用&#xff0c;小于等于0&#xff0c;用不了&#xff0c;这个值自己给。 2.特点&#xff1a; 信号量用于进程间同步&#xff0c;若要在进程间传递数据需要结合共享内存。信号量基于操作系统的 PV 操作&am…...

VS Code连接远程Linux服务器开发c++项目

1.在远程 Linux 上安装包 yum groupinstall "development tools" -y yum install cmake -y2.在 VSCode 上安装插件 C/CC/C Extension PackCMakeCMake ToolsCMake Language Support 3.连接远程Linux服务器...

stable diffusion的模型选择,采样器选择,关键词

一、Stable Diffusion的模型选择&#xff1a; 模型下载地址&#xff1a;https://civitai.com/&#xff0c;需要科学上网。 Deliberate&#xff1a;全能模型&#xff0c;prompt越详细生成的图片质量越好Realistic Vision&#xff1a;现实模型&#xff0c;生成仿真式图片&#…...

BI零售数据分析:以自身视角展开分析

随着零售业务不断扩展&#xff0c;市场竞争不断加剧&#xff0c;各层级的销售管理人员都急需一张能快速查看销售数据分析报表&#xff0c;能从中知道自己管辖内的业务最近或过去的情况&#xff0c;并依次为依据科学优化销售管理措施。这就要求零售数据分析报表信息足够多、数据…...

Maven 使用教程(三)

一、如何使用外部依赖项&#xff1f; 您可能已经注意到POM中的一个dependencies元素&#xff0c;我们一直在使用它作为示例。事实上&#xff0c;您一直在使用外部依赖项&#xff0c;但在这里我们将更详细地讨论它是如何工作的。有关更全面的介绍&#xff0c;请参阅我们的依赖机…...

行秋找工作的记录

2023-10-17 15:35-16:00 中移&#xff08;苏州&#xff09;研发中心面试 问了项目&#xff0c;还有一些我没准备到的Java八股文&#xff1a;Java类的加载过程&#xff0c;发射机制&#xff0c;redis存储结构&#xff0c;二叉平衡树等。但我也都没回答上来。应该无了。 2023-1…...

vue项目打包,使用externals抽离公共的第三方库

封装了一个插件&#xff0c;用来vue打包抽离公共的第三方库&#xff0c;使用unplugin进行插件开发&#xff0c;vite对应的功能使用了vite-plugin-externals进行二次开发 github地址 npm地址 hfex-auto-externals-plugin 自动注入插件,使用 unplugin 和 html-webpack-plugin进…...

九阳真经之各大厂校招

大学计算机系的同学要怎么努力才能校招进大厂? 秋招的大公司非常多&#xff0c;也是非常好的&#xff0c;赶上了秋招&#xff0c;你基本工作就敲定了&#xff0c;在整个应届毕业生的人群中你就占据很大的优势了。 如何准备应届校招&#xff1f; 一、做好规划&#xff0c;把…...

Go语言入门心法(五): 函数

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 一: go语言函数认知 函数相关认知升维&#xff1a;函数的功能就是把相对独立的某个相同或者时类型的功能抽象处理,使之成为一个…...

gitignore文件的语法规则

行注释&#xff1a;以"#"符号开头的行表示注释&#xff0c;Git会忽略这些行。空行&#xff1a;空行会被忽略。文件和目录规则&#xff1a; 可以使用通配符来匹配文件和目录。常用的通配符有&#xff1a; “*”&#xff1a;匹配0个或多个字符。“?”&#xff1a;匹配…...

vscode提示扩展主机在过去5分钟内意外终止了3次,解决方法

参考链接&#xff1a; https://code.visualstudio.com/blogs/2021/02/16/extension-bisect https://code.visualstudio.com/docs/setup/uninstall#_clean-uninstall 使用vscode打开jupyter notebook记事本时&#xff0c;窗口右下角提示扩展主机在过去5分钟内意外终止了3次 而…...

【算法挨揍日记】day16——525. 连续数组、1314. 矩阵区域和

525. 连续数组 525. 连续数组 题目描述&#xff1a; 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组&#xff0c;并返回该子数组的长度。 解题思路&#xff1a; 本题的元素只有0和1&#xff0c;根据题目意思&#xff0c;我们可以把题目看成找一段最…...

k8s-13 存储之secret

Secret 对象类型用来保存敏感信息&#xff0c;例如密码、OAuth 令牌和 ssh key。 敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活 。 Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里 当 kubelet 为 pod 拉…...

什么是高阶成分(HOC)

高阶组件&#xff08;Higher-Order Component&#xff0c;HOC&#xff09;是一种在React中用于组件复用和逻辑抽象的设计模式。它本质上是一个函数&#xff0c;接受一个组件作为参数&#xff0c;并返回一个新的组件。 1. HOC的作用&#xff1a; HOC允许我们在不修改原始组件的…...

深度学习硬件配置推荐

目录 1. 基础推荐2. GPU显存与内存是一个1:4的配比?3. deep learning 入门和kaggle比赛4. 有些 Kaggle 比赛数据集很大,可能需要更多的 GPU 显存,请推荐显存4. GDDR6和HBM25. HDD 或 SATA SSD1. 基础推荐 假设您作为一个深度学习入门学者的需求,以下是一份推荐的电脑硬件配…...

数仓建设(一)

想了想&#xff0c;我们的数仓的建设是基于大数据平台进行的&#xff0c;中间也经历了比较曲折的过程。 每个行业都有自身的业务区别&#xff0c;不过很多还是比较相通的。 本文将全面讲解数仓建设规范&#xff0c;从数据模型规范&#xff0c;到数仓公共规范&#xff0c;数仓各…...

Springboot整合taos时序数据库TDengine

1.首先安装TDengine服务端在linux上 TDengine多种安装包的安装和卸载 - TDengine | 涛思数据安装过程直接去官网看,非常详细简单 2.出现的问题 windows连接 invalid app version 版本不对应 版本不对应的问题,需要在linux上安装的版本和windows client版本一致,不然w…...

Epoch、批量大小、迭代次数

梯度下降 它是 机器学习中使用的迭代 优化算法&#xff0c;用于找到最佳结果&#xff08;曲线的最小值&#xff09;。 坡度 是指 斜坡的倾斜度或倾斜度 梯度下降有一个称为 学习率的参数。 正如您在上图&#xff08;左&#xff09;中看到的&#xff0c;最初步长较大&#…...

qt-C++笔记之清空QVBoxLayout中的QCheckBox

qt-C笔记之清空QVBoxLayout中的QCheckBox QVBoxLayout 和 QCheckBox 是两个类&#xff0c;都是 PyQt/PySide 中用于创建图形用户界面 (GUI) 的工具。它们通常与 Qt 库一起使用&#xff0c;Qt 是一个流行的跨平台 GUI 库&#xff0c;可以用于创建桌面应用程序。 QVBoxLayout: Q…...

pc微信39223部分算法call偏移

WechatWin.dll 基址&#xff1a;78FD0000 MD5_Init_call 7AF48C80 | 56 | push esi | 7AF48C81 | 8B7424 08 | mov esi,dword ptr ss:[esp0x8] | 7AF48C85 | 6A 4C | push 0x4C …...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...