您的位置:首页 > 编程语言

信号量互斥编程

2016-04-10 15:45 399 查看
一、信号量的作用:

信号量有时被称为信号灯,是在多线程环境下使用的一种设施,用来保证两个或者多个代码段不会被并发的调用。

主要用途是用来保护临界资源(进程互斥),进程可以根据它判断是否可以访问某些共享资源。

二、信号量的分类:

二值信号灯:信号灯的值只能取0或者1;

计数信号灯:信号灯的值可以去任意非负整数

信号量的实质:就是一个数字

操作:获取信号量

释放信号量

三、信号量的操作函数:

1.打开或者创建信号量

semget(key_tkey,intnsems,intsemflag)
//功能获取信号量的标识符当key所指定的信号量不存在时,并且semflag包含了IPC_CREAT就会创建信号量集合

//nsems
创建的这个信号量集合里面包含的信号量的数目,返回semid

key:键值

semflag:标识

IPC_CREAT;

2.操作信号量;

semop(intsemid,structsmbuf*sops,unsignednsops)

semid:要操作的信号量的标识符

nsops:要操作的信号量的个数

sops:对信号量执行什么样的操作(正代表释放,负代表获取)

四、什么是键值,键值的性质以及作用:

1.可以通过键值(数字)来找到所需的信号量



2.指定键值

1.任意指定一个

缺点:这个数已经被IPC对象(消息队列、共享内存)所使用,再与新创建的信号量关联就会失败,

2.构造一个尽量不会被别的IPC对象用的的数

方法:key_tftok(char*fname,intid);

键值的组成:



二、“公示栏”问题的程序化:

同学1

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/stat.h>
voidmain()
{
intfd;
//打开文件
fd=open("./board.txt",O_RDWR|O_APPEND);
//1.向公告板文件里写入“数学课
write(fd,"classmatch",11);
//2.暂停休息
sleep(5);
//3.向公告板文件里写入"取消"
write(fd,"iscancle",11);
close(fd);
}


同学2

#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
voidmain()
{
intfd;
//0.打开公告板
fd=open("./board.txt",O_RDWR|O_APPEND);
//1.写入“英语课考试”
write(fd,"Englishexam",20);
//关闭公告板
close(fd);
}


步骤:

先运行同学1再快速的运行同学2,则输出的结果为classmatchEnglishexam^@^@^@^@^A^[^C;iscancle^@^@

需要的结果为classmatchiscancleEnglishexam

使用信号量之后的代码

student1.c

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/ipc.h>
#include<sys/sem.h>
voidmain()
{
intfd=0;
key_tkey;
intsemid;
structsembufsops;
//创建键值
key=ftok("/home/part3/lesson38",1);
//创建并打开信号量集合
semid=semget(key,1,IPC_CREAT);
semctl(semid,0,SETVAL);
//打开文件
fd=open("./board.txt",O_RDWR|O_APPEND);
//1.1操作信号量
sops.sem_num=0;//只操作第一个信号量
sops.sem_op=-1;//负数获取这个信号量
semop(semid,&sops,1);
//1.向公告板文件里写入“数学课
write(fd,"classmatch",11);
//2.暂停休息
sleep(10);
////3.向公告板文件里写入"取消"
write(fd,"iscancle",11);
//释放信号量
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/sem.h>
#include<sys/ipc.h>
voidmain()
{
intfd;
key_tkey;
intsemid;
intret;
structsembufsops;
//创建键值
key=ftok("/home/part3/lesson38",1);
//打开信号量集合
semid=semget(key,1,IPC_CREAT);//只会打开存在的信号量,以为这个信号量已经存在
//0.打开公告板
fd=open("./board.txt",O_RDWR|O_APPEND);
ret=semctl(semid,0,GETVAL);
printf("retis%d\n",ret);
//1.1操作信号量
sops.sem_num=0;//只操作第一个信号量
sops.sem_op=-1;//负数获取这个信号量
semop(semid,&sops,1);//如果获取不到这个信号量,该进程会在这等待
//1.写入“英语课考试”
write(fd,"Englishexam",20);
//释放信号量
sops.sem_num=0;//只操作第一个信号量
sops.sem_op=+1;//负数释放这个信号量
semop(semid,&sops,1);
//关闭公告板
close(fd);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: