linux进程通信之信号量

来源:互联网 发布:ssh命令指定端口 编辑:程序博客网 时间:2024/05/22 06:57

信号量

     信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,通过控制其他的 通信资源(⽂文件,外部设备)来实现进程间通信,它本⾝身只是⼀一种外部资源的标识。信号量可以理解成一种计数器,表示当前临界资源(在多进程系统中,存在许多进程,它们共享各种资源,然而有很多资源一次只能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。)的数量,通过个欸临界区加锁,串行访问临界资源,解决二义性信号量,防止出现因多个程序同时访问一个共享资源。而信号量也是一种临界资源,通过P,V原子操作保护信号量。

工作原理:由于信号量只能进行两种操作等待和发送信号,即P操作和V操作。P操作:如果临界资源的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行 V操作:进入等待队列。V操作:给临界资源的值加1;

获得信号量

头文件:<sys/types.h>

              <sys/ipc.h>

              <sys/sem.h>

函数接口: int semget( key_t key, int nsems, int semflg )     失败返回-1

        参数key由 函数 ftok() :  key_t ftok(const char *pathname, int proj_id)返回值决定,函数ftok把一个已存在的路径名和一个整数标识得转换成一个key_t值。

       nsems表示申请信号量集中元素的个数 。

      semflg  有两个值IPC_CREAT  和IPC_EXCL

IPC_CREAT :如果IPC不存在,则创建⼀一个IPC资源,否则打开已存在资源。                                     

IPC_EXCL:只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。

如果将IPC_CREAT和IPC_EXCL标志一起使⽤用,semget()将返回⼀一个新建的IPC标识符,保证该资源是新创建的。

销毁信号量

函数接口:int semctl ( int semid, int semnum, int cmd, ... )

         参数semnum决定访问信号量集中的哪一个

               cmd:IPC_RMID :表示从内核中删除信号量

               当有 四个参数时,第四个参数的类型是 union  。调⽤用程序必须按照下面方式定义这个联合体:

union semun  {          

                             int val;               信号量集元素个数 

                             struct semid_ds *buf;  // IPC_STAT、IPC_SET 使⽤用缓存区      

                             unsigned short *array; // GETALL,、SETALL 使⽤用的数组      

                             struct seminfo *__buf; // IPC_INFO   使⽤用缓存区  }; 

该联合体没有定义在系统头文件中,因此得用户自己定义

P,V操作

函数接口:int semop (int semid, struct sembuf* sops,unsigned nsops)

       参数sops决定操作为P操作还是V操作;

struct sembuf {

short  sem_num;   //信号量集合中的信号量编号

short  sem_op  ;      //P,V操作

short  flag;               /*有三个值:0 设置信号量的默认操作,

IPC_NOWAIT   非阻塞信号量操作不等待

SEM_UNDO 选项会让内核记录一个与调用进程相关的UNDO记录,如果该进程崩溃,则根据这个进程的UNDO记录自动恢复相应信号量的计数值,如果这个进程在没有释放该信号量的情况下终止,操作系统将自动释放该进程持有的信号量,从而使另外一个进程以继续工作,防止其他进程因为得不到信号量而发生死锁现象。*/

};

       nsops为信号量集的个数

信号量的特点:

1、保护临界资源,互斥、同步访问。

2、有公共,私有接口。

3、生命周期随操作系统内核而改变。



0 0