进程间通讯—信号量

上文说共享内存的缺点可以尝试信号量弥补
多线程信号量是POSIX信号量,进程间通信是SYSTEM v信号量
POSIX sem 实现是基于futex的。 在无竞争条件下,不需要陷入内核,执行系统调用,其实现是非常轻量级的。
System V sem 则不同,无论有无竞争都要执行系统调用,因此性能落了下风。
头文件:
#include <sys/types.h>
#include <sys/ipc. h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
该函数执行成功返回信号量标示符,失败则返回-1。 参数key是函数通过调用ftok函数得到的键值,nsems代表创建信号量的个数,如果只是访问而不创建则可以指定该参数为0 ;但一旦创建了该信号量,就不能更改其信号量个数。 只要不删除该信号量,就可以重新调用该函数创建该键值的信号量,该函数只是返回以前创建的值,而不会重新创建。 semfig指定该信号茸的读写权限,
int semop(int semid, struct sembuf *sops, unsigned nsops);
struct sembuf{
short sem_num; //除非使用一组信号量,否则它为0
short sem_op; //信号量在一次操作中需要改变的数据,通常是两个数,一个是-1,即p (等待)操作,一个是+1,即v(发送信号)操作。
short sem_flg; //通常为SEM_UNDO, 使操作系统跟踪信号并在进程没有释放该信号量而终止时, 操作系统释放信号量
}
int semctl (int semid, int semnum, int cmd, … ) ;
如果有第4个参数,它通常是一个unionsemum结构,定义如下:
union semun{
int val;
struct semid_ds *buf;
unsigned short *arry;
}
cmd通常是SETVAL或IPC RMID。 SETVAL用来把信号量初始化为一个己知的值。 p值通过unionsemun中的val成员设置,其作用是在信号量第一次使用前对它进行设置。 IPC_RMID用于删除一个已经无须继续使用的信号量标识符。
信号量+共享内存关键步骤:

int semid,shmid; 
shmid = shmget(SHM_KEY, sizeof(int),iPC_CREAT| 0666); 
void *  shmptr; 
shmptr =shmat(shmid,NULL,0); 
int * data= (int *)shmptr; 
semid = semget(SEM_KEY, 2, IPC_CREATl0666) ;/*这里是创建一个semid,并且有两个信号量*/
union semun semunl;/*下面这四行就是初始化那两个信号量,一个val=O,另一个val=l*/
sernunl.val=O; 
sernctl(sernid,0,SETVAL,sernunl); 
sernunl.val=l; 
sernctl(sernid,1,SETVAL,sernunl); 
struct sernbuf sernbufl
//读
while(l){ 
sernbufl.sern_nurn=O;/*sern_nurn=O指的是下面操作指向第一个信号量,上面设置可知其val=O*/
sernbufl.sern_op=-1;川初始化值为0,再-1 的话就会等待*/
sernbufl.sern_flg=SEM_UNDO; 
sernop(sernid, &sernbufl, l);/*reader在这里会阻塞,直到收到信号*/
printf(”the  NUM:%d\n”,*data);/*输出结果*/
sernbufl. sern_nurn=l; /*这里让writer再次就绪,就这样循环*/
sernbufl.sern_op=l; 
sernbufl.sern_flg=SEM_UNDO; 
sernop ( sernid, &sernbufl, 1) ; 
}
///写
while(l){ 
sembufl.sem_num=l;川这里指向第2个信号量(sem num=l) .*I 
sembufl.sem_op=-1; /*操作是-1,因为第2个信号量初始值为1, 所以下面不会阻塞*/
sembufl.sem_flg=SEM_UNDO; 
semop(semid,&sembufl,l);/*继续叫
scanf(" %d",data);  /*用户在终端输入数据*/
sembufl.sem_num=O; /*这里指向第一个信号量*/
sembufl.sem_op=l;/*操作加川*/
sembufl.sem_flg=SEM_UNDO; 
semop(semid,&sembufl,l); 
}

如上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值