Linux C——信号量进程通信

来源:互联网 发布:网络语言蛋炒饭的意思 编辑:程序博客网 时间:2024/05/16 12:15

信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源.

进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步

1.信号量概述

信号灯与其他进程间通信方式不太相同,它主要提供对进程间共享资源访问控制机制。相当于内存中的标志,进程可以根据它判定是否能够访问某些共享资源,同时,进程也可以修改该标志。除了用于访问控制外,还可用于进程同步。信号灯有以下两种类型:

①二值信号灯:信号灯的值只能取01,类似于互斥锁。 但两者有不同:

信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;

互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。

②计数信号灯:信号灯的值可以取任意非负值

 

2.内核实现原理

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

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

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

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

 

3.与其相关的API函数

semget函数

函数作用:用于配置信号灯

函数定义:int  semget(key_t  _key ,int  _nsems, int _semflg);

参数:

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

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

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

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

_semflg:信号量的创建方式或权限。有IPC_CREATIPC_EXCL

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

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

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

 

semop函数

函数作用:用于信号灯处理

函数原型:int semop(int semid,struct sembuf *_sops,size_t _nsops);

参数:

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

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

struct   sembuf

{

    unsigned short  sem_num;//第几个信号量,第一个信号量为0

    short  sem_op;//对该信号量的操作。

    short _semflg;

};

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

返回值:成功返回0,否则返回-1

 

semctl函数

函数作用:用于控制信号灯

函数原型:int semop(int semid,struct sembuf *_sops,size_t _nsops);

参数:

_semid   信号量的标志码(ID),也就是semget()函数的返回值;

_semnum,  操作信号在信号集中的编号。从0开始。

_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设置信号量集中的一个单独的信号量的值。

返回值:调用失败返回-1,成功返回与cmd有关

 

0 0
原创粉丝点击