IPC - 信号量

信号量是一个计数器,用于为多个进程提供对共享数据的访问,其值实则表征有多少个共享资源单位可供共享应用。为了获得共享资源,进程需要执行下列操作:

1、测试控制该资源的信号量。

2、若此信号量的值为正,则进程可以使用该资源。在这种情况下,进程会将信号量值减1,表示他使用了一个资源单位。

3、否则,若此信号量的值为0,表明无可用资源,则进程进入休眠状态,直至其他进程不再使用共享资源,信号量的值增1,此时信号量大于0,处于休眠的进程被唤醒。返回步骤1。

常用的信号量形式被称为二元信号量,他控制单个资源,其初始值为1。

8.1 创建/打开信号量集合

8.1.1 函数名

semget函数

8.1.2 函数原形

   int semget(key_t key,int nsems,int semflg);

8.1.3 函数功能

   获取信号量集合的标识符semid

   当key所指定的信号量不存在时,并且semflg里面包含了IPC_CREAT,此时会创建一个信号量集合(与Open类似)。

8.1.4 所属头文件

#include<sys/types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

8.1.5 返回值

   成功:返回信号量集合的标识符(非负数)

   失败:-1

8.1.6 参数说明

   key:键值

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

   semflg:标志,可以取IPC_CREAT,

8.1.7 范例代码

 

 

8.2 操作信号量

8.2.1 函数名

   semop函数

8.2.2 函数原形

   int semop(int semid,struct sembuf *sops,unsigned nsops)

8.2.3 函数功能

   操作信号量集合里面的信号量

8.2.4 所属头文件

   #include<sys/types.h>

   #include<sys/ipc.h>

   #include<sys/sem.h>

8.2.5 返回值

   成功:返回0

   失败:返回-1

8.2.6 参数说明

semid:待操作的信号量集合标志符

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

nsops:要操作多少个信号量

示例例程:两个学生共用一块黑板发布通知消息

student1:

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

void main()
{
	int fd=0;
	key_t key;
	int semid=0;
	struct sembuf sops;

	//创建键值
	key=ftok("/home",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;//减1
	semop(semid,&sops,1);
	
	//写入“数学课”
	write(fd,"class math ",11);

	//暂停休息
	sleep(10);//延时10秒钟

	//写入“取消”	
	write(fd,"is cancel! ",11);

	//释放信号量
	sops.sem_num=0;
	sops.sem_op=1;//+1
	semop(semid,&sops,1);
	
	//关闭文件
	close(fd);
}


student2:

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

/*************
 *1.打开文件
 *2.写入“英语课考试”
 *3.关闭文件
 *************/

void main()
{
	key_t key;
	int semid=0;
	int fd=0;
	struct sembuf sops;
	int ret;

	//创建主值
	key=ftok("/home",1);

	//打开信号量集合
	semid=semget(key,1,IPC_CREAT);
	
	ret=semctl(semid,0,GETVAL);
	printf("ret is %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 test. ",14);

	//释放信号量
	sops.sem_num=0;
	sops.sem_op =1;
	semop(semid,&sops,1);

	//关闭文件
	close(fd);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值