信号量互斥编程

1.核心理论

信号量

信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源(进程互斥)。进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可以用于进程同步。

信号量分类:

二值信号量:信号量的值只能取0或1

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

2.函数学习

创建/打开信号量集合

函数名:semget

函数原型:int semget(key_t  key, int nsems, int semflg);

函数功能:获取信号量集合的标识符,当key所指定的信号量不存在时并semflag为IPC_CREAT时创建信号量集合

头文件:<sys/types.h> <sys/ipc.h> <sys/sem.h>

返回值:成功:返回信号量集合的标识符  失败:-1

参数说明:key:信号量对应的键值  

semflag:标志,可以取IPC_CREAT

nsems:创建的信号量集合里面包含的信号量数目

(指定键值):

* 任意指定一个数:缺点:这个数已经被别的IPC对象(消息队列,共享内存)所使用,在与新创建的信号量关联时就会失败。

* 构造一个尽量不会被别的IPC对象用到的数,方法 key_t ftok(char *fname, int id);

操作信号量

函数名:semop

函数原型:int semop(int semid, struct sembuf *sops, unsigned nsops);

函数功能:操作信号量集合里的信号量

头文件:<sys/types.h> <sys/ipc.h> <sys/sem.h>

返回值:成功:0  失败:-1

参数说明:semid:要操作的信号量集合的标识符  

nsops:要操作多少个信号量

sops:对信号执行什么样的操作

3.综合实例

/* student1.c */

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{
	int fd = 0;
	key_t key;
	int semid;
	struct sembuf sops;
	
	/* 创建键值 */
	key = ftok("/root/",1);

	/* 创建并打开信号量集合 */
	semid = semget(key,1,IPC_CREAT);
	
	/* 设置信号量初始值为1 */
	semctl(semid,0,SETVAL,1);
	
	/* 打开文件 */
	fd = open("./board.txt",O_RDWR|O_APPEND);
	
	/* 获取信号量 */
	sops.sem_num = 0;
	sops.sem_op = -1;
	semop(semid,&sops,1);
	
	/* 向公告板文件里写入“数学课” */
	write(fd,"class math",10);
	
	/* 暂停休息 */
	sleep(10);
	
	/* 向公告板写入取消 */
	write(fd," is cancel",10);
	
	/* 释放信号量 */
	sops.sem_num = 0;
	sops.sem_op = 1;
	semop(semid,&sops,1);
	
	close(fd);
}

/* student2.c */

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>

void main()
{
	int fd = 0;
	key_t key;
	int semid;
	struct sembuf sops;
	int ret;
	
	/* 创建键值 */
	key = ftok("/root/",1);
	
	/* 打开信号量集合 */
	semid = semget(key,1,IPC_CREAT);
	
	ret = semctl(semid,0,GETVAL);
	printf("%d\n",ret);
	
	/* 打开公告板文件*/
	fd = open("./board.txt",O_RDWR|O_APPEND);
	
	/* 获取信号量 */
	sops.sem_num = 0;
	sops.sem_op = -1;
	semop(semid,&sops,1);
	
	/* 写入英语课“考试” */
	write(fd," english exam",13);
	
	/* 释放信号量 */
	sops.sem_num = 0;
	sops.sem_op = 1;
	semop(semid,&sops,1);
	
	close(fd);
}

执行结果board.txt为:class math is cancel english exam
而不是class math english exam
 is cancel
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值