linux 获取和释放信号量_Linux应用编程之"信号量"

本文介绍了Linux中的信号量概念,包括信号量的类型和使用模型。信号量作为进程同步的一种方式,分为二值信号量和计数信号量。文章详细讲解了信号量API,如semget()和semop(),并阐述了如何通过信号量实现进程的互斥和同步。
摘要由CSDN通过智能技术生成
1f2220f763a0ad94e321fd7e334adb8b.gif 关注、星标公众号,直达精彩内容

7263e31986307ce7672682732b1f4c2b.png

ID:嵌入式情报局

作者:情报小哥

1什么是信号量?

01

形象理解   

    信号量说得简单一点就是一个非负计数整形变量,一旦占用了就会减1,释放就会加一,如果进程/线程需要占用信号量,而此时信号计数为0,则会把当前进程堵塞。

    如果再形象一点那就类比生活中的交通灯,把程序的运行比作来往的车辆,而十字路口比作共享资源,信号量就类似于交通灯,起到协调各个进程有序的访问共享资源,这样就形成了进程的同步。

c8ef39e2f601e649cc22da3351087bd8.png

02

信号量分类   

信号量也是一种进程中通信的方式,而该进程通信方式与前面介绍的稍有不同,其目的不是为了传递数据,而是用来保护共享资源(信号量也属于临界资源),使共享资源在任何时刻只能有规定的进程访问。

信号量主要分为两类:

  • 二值信号量:信号量的值只有0和1,这和互斥量很类似,若资源被锁住,信号量的值为0,若资源可用,则信号量的值为1。但是信号量作为一种进程中的通信方式,与互斥量不同在于,互斥量只能由上锁的进程进行解锁,而信号量可以由其他进程进行解锁。
  • 计数信号量:信号量的值在0到一个大于1的限制值之间,该计数表示可用的资源的个数。

03

使用参考模型  

我们把P表示信号量的减1操作,而V表示信号量的加1操作,当然这里的加减1非我们平时的++或者--,PV都属于原子操作,下面简单的画一下信号量形成互斥的基本模型,如下图所示 :

1b3b3e5e92ffa0ec6ca358c2697d5c35.png

当信号量单做互斥使用均初始化为1,当一个进程进行P操作便会减1,从而把临界资源锁定,在进程1还没有进行V操作释放信号量之前,若进程2进行P操作就会进行堵塞,从而等待进程1释放信号量,一旦进程1执行V操作,那么进程2便又有机会执行P操作(当然如果进程1一直不进行V操作,那么就会形成死锁),进程2利用临界资源,从而保障了临界资源的独占。

如果使用信号量来进行同步,就需要了解资源的特性和各个进程的制约关系,从而来确定信号量的初值以及PV操作。

2一些API介绍

    这里小哥就介绍一下信号量的相关API,为后面的线程知识打基础。

1、创建(获取)信号量

8a31cd4c680d1eb50ec8cb4c57bbcab2.png

semget()系统调用返回与参数键关联的SystemV信号量集标识符。

创建情形1 : 如果key的值为IPC_PRIVATE,

创建情形2 : 没有与key相关联的现有信号量集,并且在semflg中指定了IPC_CREAT,则创建一组新的nsems信号量。

如果semflg同时指定IPC_CREAT和IPC_EXCL,并且键已经存在一个信号量集,那么semget()失败,errno设置为EEXIST

key : IPC 键值,通常由 ftok() 生成,该值与创建消息队列、共享内存中使用的类似。

nsems:指定集合中包含的信号量个数;

semflg:该参数是多个标识的组合,其低 9 位指定用户对该信号量集合的权限。创建消息队列时常用0666 | IPC_CREAT。

2、信号量操作

be3c54736fda8bec10b44b426f77e150.png

该函数用于指定信号量集合中的某个信号量的动作 : 获取或者释放。成功返回 0,失败返回 -1。

semid:由 semget() 返回的信号量集合 ID;

sops:该参数指定了对 semid 信号量集合中某些信号量的操作,该值为 struct sembuf 结构体数组的首地址。其结构体内容如下:

1struct sembuf
2{
3    unsigned short sem_num;  /* semaphore number */
4    short          sem_op;   /* semaphore operation */
5    short          sem_flg;  /* operation flags */
6}

sem_num:信号量集合中的信号量序号且从 0 开始,信号量的总数由 semget() 中的 nsems 指定。

sem_op :指定对序号为 sem_num 的信号量的操作。

  • sem_op > 0,表示释放信号量,值的大小表示释放的信号量的个数。
  • sem_op = 0,进程阻塞直到信号量的相应值为0,当信号量已经为0,函数立即返回。
  • sem_op ,其绝对值表示程序想要占用的信号量的数量,如果信号量满足,将该信号量的值减去sem_op的绝对值,函数成功返回。如果此时 sem_num 指定的信号量没有足够的数量,那么程序将阻塞。
sem_flg:取值 SEM_UNDO 和 IPC_NOWAIT。
  • IPC_NOWAIT : 指定对 sem_num 信号量的操作非阻塞。
  • SEM_UNDO : 表示撤销操作。即不论程序是正常还是异常结束,sem_num 指定的信号量的值都会恢复为调用 semop() 之前的值,主要用于防止程序异常结束时未将占用的资源释放,导致资源永远被锁定的情况出现。
nsops:表示 sops 参数指定的数组中有几个成员。即想要操作集合中的信号量的数量。

3最后

这里小哥就介绍了一下信号量和相关的API操作, 希望本文能够对你有帮助,今天就分享到这里,下期精彩见!

推荐好文  点击蓝色字体即可跳转

☞ 专辑|Linux应用程序编程大全fc7c00ebbd19835c9115a35289ec20e1.gif

☞ 专辑|手撕C语言fc7c00ebbd19835c9115a35289ec20e1.gif

我是情报小哥,一名嵌入式玩家!

8cd33b5639307dbea60b4710cea1c388.gif

1f1ca884e13d8ad209734c5f24559687.png

长按前往图中包含的公众号关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值