一、信号量互斥
公示栏问题:同学A在公示栏上写“数学课取消”,同学B然后又写了“英语课考试”。但是当,同学A写下“数学课”后。出去了一下,这是同学B写了“英语课考试”,同学A再回来写“取消”。这时我们所要传达的意思就完全不一样了。所以需要引入互斥。
1. 信号量
信号量(又名:信号灯)与其他进
程间通信方式不大相同,主要用途是保护临界资源(进程互斥)。进程可以根据它判定是否能够访
问某些共享资源。除了用于访问
控制外,还可用于进程同步。
2.信号量分类:
二值信号灯:信号灯的值只能取0或1
计数信号灯:信号灯的值可以取任意非负值。
3.指定键值
①任意指定一个数
缺点:这个数已经被别的IPC对象(消息队列,共享内存)
所使用了,在与新创建的信号量关联时就会失败。
②构造一个尽量不会被别的IPC对象用到的数
方法:使用key_t ftok( char * fname, int id )
Ftok工作原理:将fname和id相组合,组成一个信号量
4.程序代码
student1.c
-
#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;
-
int ret;
-
key_t key;
-
int semid;
-
struct sembuf sops;
-
-
/*创建键值*/
-
key = ftok("/home", 1);
-
-
/*创建并打开信号量集合*/
-
semid = semget(key,1,IPC_CREAT);
-
ret = semctl(semid, 0, SETVAL, 1); //将信号量个数初始设置为1
-
-
/*0.打开文件*/
-
fd = open("./board.txt",O_RDWR|O_APPEND);
-
if(fd < 0)
-
{
-
printf("file open fialed.\n");
-
return;
-
}
-
/*获取信号量*/
-
sops.sem_num = 0;
-
sops.sem_op = -1;
-
ret = semop(semid, &sops,1);
-
-
-
/*1.向文件公告板写入“数学课”*/
-
write(fd, "class math ", 11);
-
/*2.暂停休息*/
-
sleep(10);
-
/*3.向公告板写入“取消”*/
-
write(fd, "is cancel ",11);
-
-
/*释放信号量*/
-
sops.sem_num = 0;
-
sops.sem_op = 1;
-
ret = semop(semid, &sops, 1);
-
-
close(fd);
-
}
student2.c
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <unistd.h>
-
#include <fcntl.h>
-
#include <sys/ipc.h>
-
#include <sys/sem.h>
-
-
void main()
-
{
-
int fd;
-
int ret;
-
key_t key;
-
int semid;
-
struct sembuf sops;
-
/*打开信号量*/
-
key = ftok("/home",1);
-
semid = semget(key, 1, IPC_CREAT);
-
-
/*打开文件*/
-
fd = open("./board.txt", O_RDWR|O_APPEND);
-
-
ret = semctl(semid, 0, GETVAL);
-
printf("the value of sem is %d\n",ret);
-
-
/*获取信号量*/
-
sops.sem_num = 0;
-
sops.sem_op = -1;
-
semop(semid, &sops, 1);
-
-
/*写入“英语课考试”*/
-
write(fd, "english exam", 20);
-
-
/*释放信号量*/
-
sops.sem_num = 0;
-
sops.sem_op = 1;
-
semop(semid, &sops, 1);
-
-
/*结束*/
-
close(fd);
-
}
二、信号量同步
1.进程同步
一组并发进程进行互相合作、互相等待,
使得各进程按一定的顺序执行的过程称为进程间的同步。
2.生产者消费者问题
生产者生产完产品后,消费者才能把产品拿走。如果还没生产完,消费者就拿走的话,会造成不同步。
3.程序代码
通过生产者设置信号量为0后,只有生产完产品才释放信号量。之后消费者才能取走产品。
productor.c
-
#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;
-
key_t key;
-
struct sembuf sops;
-
int semid;
-
/*创建信号量*/
-
key = ftok("/root", 1);
-
semid = semget(key, 1, IPC_CREAT);
-
semctl(semid, 0, SETVAL, 0);
-
-
/*创建文件*/
-
fd = open("./product.txt", O_RDWR|O_CREAT, 0666);
-
-
/*休息*/
-
sleep(20);
-
-
/*往文件写入内容*/
-
write(fd, "write something.", 16);
-
-
/*释放信号量*/
-
sops.sem_num = 0;
-
sops.sem_op = 1;
-
semop(semid, &sops, 1);
-
-
close(fd);
-
}
customer.c
-
#include <sys/types.h>
-
#include <stdlib.h>
-
#include <sys/ipc.h>
-
#include <sys/sem.h>
-
-
void main()
-
{
-
key_t key;
-
int semid;
-
struct sembuf sops;
-
int ret;
-
/*获取信号量*/
-
key = ftok("/root", 1);
-
semid = semget(key, 1, IPC_CREAT);
-
-
sops.sem_num = 0;
-
sops.sem_op = -1;
-
sops.sem_flg = SEM_UNDO;
-
ret = semop(semid, &sops, 1);
-
printf("ret is %d",ret);
-
-
/*取走文件*/
-
system("cp ./product.txt ./ship/");
-
-
// sops.sem_num = 0;
-
// sops.sem_op = 1;
-
// semop(semid, &sops, 1);
-
}
阅读(650) | 评论(0) | 转发(0) |