进程通信之信号量
来源:互联网 发布:网络机柜价格 编辑:程序博客网 时间:2024/06/04 18:16
一 信号量(信号灯)概念:
信号量提供一种访问机制,让一个临界区同一时间只有一个进程在访问他,也就是说信号量用来协调进程对共享资源的访问的。
信号量是一个特殊的变量,程序对其访问都是原子操作,只允许对他进行等待(P)和发送信息(V)的操作。最简单的信号量只能取0和1的变量,这也是信号量最常见的一种形式,叫做二进制信号量。可以取多个正整数的信号量称为信号量。
信号量与其他进程间通信方式不大相同,主要用途是保护临界资源。进程可以根据他判断是否能够访问某些资源。
当进程A要获取临界资源S时,首先要获取临界资源的信号量M,M的初始值为1,当获取到M并发现M的值大于1时,可以反问临界资源M,且信号量-1,M=0。当进程B也要访问临界资源S时,也要首先获取临界资源S的信号量M,发现M的值为0时,无法获取临界资源S,进程B阻塞等待。当进程A访问完临界资源后,信号量M加1,变为M=1,同时唤醒进程B,使得B能够访问临界资源S,以此类推,交替访问临界资源S。
二 信号量创建:int semget(key_t key, int num_sems, int sem_flags); 成功返回一个相应信号标识符,失败返回-1
1,key 键值,由ftok提供,第一个参数key是整数值(唯一非零),不相关的进程可以通过它访问一个信号量,它代表程序可能要使用的某个资源,程序对所有信号量的访问都是间接的,程序先通过调用semget函数并提供一个键,再由系统生成一个相应的信号标识符(semget函数的返回值),只有semget函数才直接使用信号量键,所有其他的信号量函数使用由semget函数返回的信号量标识符。
2,num_sems指定需要的信号数目,它的值几乎总是1;
3,sem_flags 是一组标志,当想要当信号量不存在时创建一个新的信号量,可以和值IPC_CREAT做按位或操作。设置了IPC_CREAT标志后,即使给出的键是一个已有信号量的键,也不会产生错误。而IPC_CREAT | IPC_EXCL则可以创建一个新的,唯一的信号量,如果信号量已存在,返回一个错误。
三 操作 :改变信号量的值
int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);
1,sem_id 是由semget返回的信号量标识符
2,sembuf
struct sembuf
{
short sem_num;//除非使用一组信号量,否则它为0
short sem_op;//信号量在一次操作中需要改变的数据,通常是两个数,一个是-1,即P(等待)操作,
//一个是+1,即V(发送信号)操作。
short sem_flg;//通常为SEM_UNDO,使操作系统跟踪信号,
//并在进程没有释放该信号量而终止时,操作系统释放信号量
};
3, nsops:信号操作结构的数量,恒大于或等于1
四 控制 int semctl(int sem_id, int sem_num, int command, ...);
如果有第四个参数,它通常是一个union semum结构,定义如下:
union semun
{
int val;
struct semid_ds *buf;
unsigned short *arry;
};
1,sem_id信号量标识符
2,操作信号在信号集中的编号,第一个信号的编号是0
3,command:
STEVAL:把信号量初始化为一个已知的值。P这个值通过union semun中的val成员设置,其作用是在信号量第一次使用前对他进行设置
IPC_RMID:删除一个无需使用的信号量标识符
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>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(Linux specific) */};int sem_init(int sem_id){//int semctl(int semid, int semnum, int cmd, ...);union semun sem;sem.val = 1;int ret = semctl (sem_id,0,SETVAL,sem);//信号量的初始化if(ret == -1){perror("semctl ");return -1;}return 0;}int sem_del(int sem_id){int ret = semctl (sem_id,0,IPC_RMID);//删除信号量if(ret == -1){perror("semctl ");return -1;}return ret;}//信号量的P操作int sem_p(int sem_id){struct sembuf sem;sem.sem_num = 0;sem.sem_op = -1;sem.sem_flg = SEM_UNDO;int ret = semop(sem_id,&sem,1);return ret;}//信号量的V操作int sem_v(int sem_id){struct sembuf sem;sem.sem_num = 0;sem.sem_op = 1;sem.sem_flg = SEM_UNDO;int ret = semop(sem_id,&sem,1);return ret;}
- 进程通信之信号量
- 进程通信之信号量
- 进程通信之信号量
- 进程通信之信号量
- 【进程通信】之信号量
- 进程通信之信号量
- 进程通信之四 信号量
- 进程间通信之信号量
- Linux进程通信之信号量
- linux 进程通信之 信号量
- 进程间通信之信号量
- 进程间通信之信号量
- 进程间通信之信号量
- linux进程通信之信号量
- 进程间通信之信号量
- 进程间通信之信号量
- 进程间通信之信号量
- Linux--进程通信之信号量
- angular中的$http是异步的,如何实现同步操作
- 平衡二叉树(转自百度百科)
- HTML5 和移动端 WebView 缓存机制解析与实战
- 二叉树的基本操作c++
- ZigBee CC2530 Z-Stack 21 组播通信
- 进程通信之信号量
- CFM入门
- 网易2018内推笔试题解析(交错01串)
- HashSet的重写comparbleble和compartor比较方法
- 计算机是怎么做乘法运算的
- 观央视新闻调查《我是黑客》的一些感悟
- SCU
- hdu 1069
- Android进阶之创建快捷方式