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

嵌入式学习——进程间通信方式(5)—— 信号量

一、基本概念

信号量和之前的所说的管道、共享内存、消息队列、信号是不一样的,信号量的本质是一个整型计数器,不以传输数据为目的,主要是对临界资源进行一个保护,例如我们在操作共享内存时,要配合信号量来进行使用,目的是为了对共享内存数据的保护,防止多进程同时操作出现数据混乱。

二、工作原理

信号量只有两种操作:等待信号和操作信号,就是P操作和V操作(都是原子操作),P操作是使用临界资源,而V操作是释放临界资源。

P操作:申请临界资源进行使用(信号量大于0),则占用一个资源,把信号量减去1,若此时的信号量为0,则阻塞,一直在等待队列进行等待,直到有资源进行释放。

V操作:如果在等待队列有进程在等待资源,则唤醒阻塞的进程,如果没有的话,释放资源,把信号量的值加一。

原子操作:在进行原子操作时,不会被打断,直到操作完成

三、使用流程

1)创建或获取信号量

int semget(key_t key, int nsems, int semflg);

key:① 通过调用key_t ftok(const char *pathname, int proj_id)来进行获取;这个函数是通过指定的文件路径和计划编号合成一个key值。

         ② IPC_PRIVATE 内核会保证创建一个新的,唯一的IPC对象,这是一个宏定义,其值为0。

nsems:本参数用于在创建信号量的时候,表示可用的信号量数目。

semflg:IPC_CREAT 若系统中有相同的key值,则返回信号量的标识符;若不存在则创建,要与 0600 结合  给相应的权限(IPC_CREAT | 0600)。

               IPC_EXCL  如果系统中有相同的key值,则会报错;不存在则创建。

注:可以在linux下输入  ipcs -l    查看信号量最大值,最大操作数,还有消息队列和共享内存的相关信息。

2)初始化信号量

int semctl(int semid, int semnum, int cmd, ...);

semid:就是创建/获取信号量时,返回的描述符。

semnum:表示第几个信号量,取值范围是0~num-1。

cmd:操作该信号的指令,有如下这些:       

  • IPC_SET:通过第四个参数的buf来设定信号量集相关联的semid_ds中信号量集合权限为sem_perm中的uid,gid,mode。

  • IPC_RMID:从系统中删除该信号量集合。

  • GETVAL:返回第semnum个信号量的值。

  • SETVAL:设置第semnum个信号量的值,该值由第四个参数中的val指定。

  • GETPID:返回第semnum个信号量的sempid,最后一个操作的pid。

  • GETNCNT:返回第semnum个信号量的semncnt。等待semval变为大于当前值的线程数。

  • GETZCNT:返回第semnum个信号量的semzcnt。等待semval变为0的线程数。

  • GETALL:去信号量集合中所有信号量的值,将结果存放到的array所指向的数组。

  • SETALL:按arg.array所指向的数组中的值,设置集合中所有信号量的值。

  • IPC_STAT:获取此信号量集合的semid_ds结构,存放在第四个参数的buf中。

3)操作信号量

int semop(int semid, struct sembuf *sops, size_t nsops);
  • semid:System V信号量的标识符,用来标识一个信号量。

  • sops:是指向一个struct sembuf结构体数组的指针,该数组是一个信号量操作数组。

  • nsops:表示上面sops数组的数量,如只有一个sops数组,nsops就设置为1。

4)销毁信号量

int semctl(int semid, int semnum, int cmd, ...);

在销毁信号量时,指定描述符,把cmd指定为IPC_RMID即可。


http://www.kler.cn/a/429123.html

相关文章:

  • CV 图像处理基础笔记大全(超全版哦~)!!!
  • HackMyVM-Klim靶机的测试报告
  • Web前端------表单标签
  • 什么是长连接?Netty如何设置进行长连接?
  • 个人vue3-学习笔记
  • ToDesk设置临时密码和安全密码都可以当做连接密码使用
  • 22. 五子棋小游戏
  • 阿里云PolarDB 如何进行数据恢复,文档总结
  • 【Qt】QMainWindow、QWidget和QDialog的区别?
  • Oracle 19C RU补丁升级,从19.7to19.25 -单机
  • 5G模组AT命令脚本-关闭模组的IP过滤功能
  • 驱动断链的研究
  • 【C++AVL树】枝叶间的旋律:AVL树的和谐之道
  • H5游戏出海如何获得更多增长机会?
  • 2024年12月9日Github流行趋势
  • Yocto bitbake and codeSonar
  • 【5G】Spectrum 频谱
  • 关于网页自动化工具DrissionPage进行爬虫的使用方法
  • flink终止提交给yarn的任务
  • 什么是CSS盒模型?box-sizing又是什么?
  • 架构09-可靠通信
  • Unity 策略游戏地图上的网格是如何实现的
  • 游戏引擎学习第38天
  • css定义多个延时动画案例代码
  • 基于单片机的智能农田灌溉节水系统设计及应用
  • centos部署SkyWalking并在springcloud项目中用法举例