系统编程之进程间的 信号量 通信(4)

系列文章目录

第一章 系统编程之多进程

第二章 系统编程之进程间的 管道 通信(1)

第二章 系统编程之进程间的 信号 通信(2)

第二章 系统编程之进程间的 共享内存 通信(3)

第二章 系统编程之进程间的 信号量 通信(4)

第二章 系统编程之进程间的 消息队列 通信(5)

前言

        这篇文章将讲述另一种进程间通信的机制——信号量。注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物。

一、信号量

        信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

作用:协调多个进程在通信的时候,对于共享资源(临界区资源)的访问。

1 信号量的工作原理

        由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

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

2 信号量相关命令

ipcs  -s                           // 查看信号量    

ipcrm  -s   信号量的ID    // 删除信号量  

3 相关的接口函数

3.1 申请信号量(信号灯)

#include <sys/sem.h>                

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

参数1:key(唯一非零):不相关的进程可以通过它访问一个信号量

参数2:nsems:你打算申请多少个信号量

参数3:sem_flags:代表一组标志,当想要当信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作

返回值:成功返回一个相应信号标识符(非零)

               失败返回-1

semget(key, 2,IPC_CREAT|IPC_EXCL|0777);

3.2 操作信号量

PV操作:                      

        p操作:对信号量的值做减法运算                      

        v操作:对信号量的值做加法运算                

tips:  可以把semop函数做二次封装                              

int  p操作(int 减少多少,int 哪个信号量)                              

{                                      

        semop(int semid, struct sembuf *sops, size_t nsops);                              

}                              

int  v操作(int 减少多少,int 哪个信号量)                              

{                                    

        semop(int semid, struct sembuf *sops, size_t nsops);                              

}                

int semop(int semid, struct sembuf *sops, size_t nsops);                          

返回值:成功0  失败-1                              

参数1:sops :结构体指针                                      

         struct sembuf                                      

        {                                            

             unsigned short sem_num;   //信号量的序号,序号从0开始

             short          sem_op;             //你想对信号量进行p操作还是v操作

             short          sem_flg;             //SEM_UNDO,pv操作改变信号量的值,下次重新运                                                                行,信号量恢复成原始值                                      

        }                                      

参数2:nsops:struct sembuf的个数,一般设置为1

3.3 设置信号量的值,获取值,删除信号量 

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

参数:semnum:信号量的序号                                    

           cmd:IPC_RMID //删除信号量

                      GETVAL   //我想获取信号量的值

                      SETVAL   //我想设置信号量的值  

                            

semctl(semid, 0,  IPC_RMID );   //我要删除第一个信号量                                                        

semctl(semid, 1,  IPC_RMID );   //我要删除第二个信号量                                                         int value=semctl(semid, 0,  GETVAL); //我要获取第一个信号量的值,返回值就是信号量的值 semctl(semid, 0, SETVAL,1);  //我要把第一个信号量的值设置为1

4 信号量的特点 

  • 信号量的值不能是负数,信号量值为0,你还要进行p操作,会阻塞当前进程,v操作做加法,不会阻塞进程。               
  • 信号量表示进程拥有的资源的数量,比如:值是5,进程拥有5个资源  p操作剥夺我的资源  v操作增加资源。

总结

以上就是本文要讲的内容,本文仅仅简单介绍了信号量的原理和使用方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值