本质:计数器。当前资源个数
生命周期:随内核
本身不具有数据交换的功能,是通过控制其他通信资源(文件、外部设备)来实现进程间通信,本身是一种外部资源的标识。在此过程中负责数据操作的互斥与同步功能。
互斥:独占临界资源(排他)
同步:建立在互斥基础上(顺序性)
主要作用:协调进程对共享资源的访问,保证在任一时刻,只有一个执行线程访问代码的临界区域。(其中共享内存的使用就要用到信号量)
操作:
p操作:申请资源(以信号量集为单位申请)
v操作:释放资源
int semctl(int semid, int semnum, int cmd, ...); //系统调用它用来执行在信号量集上的控制操作
或者int semctl(int semid,int semnum,int cmd, /*union semun arg*/);
semid:信号量集IPC标识符
semnum:操作信号在信号量集中的编号(第一个信号的编号是0)
cmd中的操作:
IPC_STAT:读取一个信号量集的数据结构semid_ds,将其存储在semun中的buf参数中
IPC_SET:设置信号量集的数据结构semid_ds的元素ipc_perm,其值取自semun中的buf参数
IPC_RMID:将信号量集从内存中删除
IPC_SETVAL:设置信号量集中的一个单独的信号量的值
arg:代表一个semun的实例(它是一个联合类型的副本,而不是一个指向联合类型的指针)
union semun
{
int val; //value for SETVAL
struct semid_ds *buf; //buffer for IPC_STAT&IPC_SET,代表内核中使用的信号量的数据结构
unsigned short *array; //array for GETALL&SETALL,指针
struct seminfo *__buf; //buffer for IPC_INFO
};
struct semid_ds
{
struct ipc_perm sem_perm; //Ownership and permissions
time_t sem_otime; //last semop time
time_t sem_ctime; //last change time
unsigned short sem_nsems; //No. of semaphores in set
};
成功:返回一个正数
失败:-1
int semget(key_t key, int nsems, int semflg); //获取与某个键关联的信号量集标识
nsems:创建的信号量集中的信号量的个数,该参数只在创建信号量集时有效
成功:返回信号量集IPC标识符
失败:-1
int semop(int semid, struct sembuf * sops, unsigned nsops); //P、V操作通过调用semop函数实现,大于0表示当前可用的资源数的数量,小于0表示等待使用该资源的进程个数
semid:信号集的识别码,通过semget获取
sops:指向存储信号操作结构的数组指针
struct sembuf
{
unsigned short sem_num; //semaphore number,操作信号在信号集中的编号,第一个编号是0
short sem_op; //semaphore operation
short sem_flg; //operation flags
};
sem_op:若其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;若其值为负数,而其绝对值又大于信号的现值,操作会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;若其值为0,则操作将暂时阻塞,直到信号的值变为0
sem_flg:信号操作标志
IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,并立即返回
IPC_UNDO //程序结束时(不论正常或异常),保证信号值会被重设为semop()调用前的值。避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定
nsops:信号操作结构的数量,恒大于或等于1
成功:0
失败:-1
进程间通信之信号量
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:https://www.heiqu.com/6437e80afd3e7bfecf3b6e3523798635.html