代码:
文件1:
#ifndef __head__
#define __head__
//声明创建信号灯集并初始化函数
int init_sem(int semnum);
//P操作函数
int P(int semid,int semno);
//V操作函数
int V(int semid,int semno);
//删除信号灯集函数
int del_sem(int semid);
#endif
文件2:
#include<myhead.h>
#include"sem.h"
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
//自定义初始化信号灯函数
int set_semno_value(int semid, int semno, int semval)
{
//定义共用体
union semun us;
us.val = semval;
//调用semctl对灯进行初始化
if(semctl(semid, semno, SETVAL, us) == -1)
{
perror("semctl error");
return -1;
}
return 0;
}
//创建信号灯集并初始化函数的定义
int init_sem(int semnum)
{
//创建key值
key_t key;
if((key = ftok("/", 't')) ==-1)
{
perror("ftok error");
return -1;
}
//创建信号灯集
int semid;
if((semid = semget(key, semnum, IPC_CREAT|IPC_EXCL|0664)) == -1)
{
if(errno == EEXIST)
{
//表明信号灯集已经存在,直接打开即可
semid = semget(key, semnum, IPC_CREAT|0664);
//将信号灯集打开后,直接将信号灯集id返回
return semid;
}else
{
perror("semget error");
}
return -1;
}
//给信号灯集进行初始化
for(int i=0; i<semnum; i++)
{
if(i == 0||i==3)
{
//设置信号灯的初始值
//参数1:信号灯集
//参数2:要操作的信号灯编号
//参数3:要设置的值
set_semno_value(semid, i, 1);
}else
{
set_semno_value(semid, i, 0);
}
}
return semid;
}
//P操作函数的定义
int P(int semid, int semno)
{
//定义一个操作结构体变量
struct sembuf buf;
buf.sem_num = semno; //要操作的信号灯编号
buf.sem_op = -1; //表示要进行申请资源
buf.sem_flg = 0; //表示阻塞申请资源
if(semop(semid, &buf, 1) == -1)
{
perror("P error");
return -1;
}
return 0;
}
//V函数的定义
int V(int semid, int semno)
{
//定义一个操作结构体变量
struct sembuf buf;
buf.sem_num = semno; //要操作的信号灯编号
buf.sem_op = 1; //表示要进行申请资源
buf.sem_flg = 0; //表示阻塞申请资源
if(semop(semid, &buf, 1) == -1)
{
perror("V error");
return -1;
}
return 0;
}
//删除信号灯集的函数的定义
int del_sem(int semid)
{
//删除信号灯集
if(semctl(semid, 0, IPC_RMID, 0) == -1)
{
perror("delete error");
return -1;
}
return 0;
}
文件3:
#include<myhead.h>
#include"sem.h"
int main(int argc, const char *argv[])
{
//打开信号灯集
int semid = init_sem(4);
//创建key值
key_t key;
if((key = ftok("/", 'k')) == -1)
{
perror("ftok error");
return -1;
}
//创建共享内存
int shmid;
if((shmid = shmget(key, 4096, IPC_CREAT|0664)) == -1)
{
perror("shmget error");
return -1;
}
//映射内存
char *addr = NULL; //指向共享内存段
if((addr = shmat(shmid, NULL, 0)) == (void*)-1)
{
perror("shmat error");
return -1;
}
//定义pid号
pid_t pid;
pid=fork();
if(pid>0){
while(1)
{
//等待0号灯的资源
P(semid, 0);
//从终端获取数据放入共享内存中
fgets(addr, 4096, stdin);
addr[strlen(addr)-1] = '\0';
//释放1号灯的资源
V(semid, 1);
if(strcmp(addr, "quit") == 0)
{
wait(NULL);
break;
}
}
}else if(pid==0){
while(1){
//等待2号灯的资源
P(semid,2);
//从物理内存中读取数据
printf("获取的数据为:%s\n",addr);
//释放3号灯的资源
V(semid,3);
if(strcmp(addr, "quit") == 0)
{
exit(EXIT_SUCCESS);
break;
}
}
}else{
perror("fork error");
return -1;
}
//取消映射
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
return 0;
}
文件4:
#include<myhead.h>
#include"sem.h"
int main(int argc, const char *argv[])
{
//创建信号灯集
int semid = init_sem(4);
//创建key值
key_t key;
if((key = ftok("/", 'k')) == -1)
{
perror("ftok error");
return -1;
}
//创建共享内存
int shmid;
if((shmid = shmget(key, 4096, IPC_CREAT|0664)) == -1)
{
perror("shmget error");
return -1;
}
//映射内存
char *addr = NULL; //指向共享内存段
if((addr = shmat(shmid, NULL, 0)) == (void*)-1)
{
perror("shmat error");
return -1;
}
//定义进程号
pid_t pid;
pid=fork();
if(pid>0){
while(1)
{
//申请1号灯的资源
P(semid, 1);
//读取共享内存的数据
printf("共享内存中的数据为:%s\n", addr);
//释放0号灯的资源
V(semid, 0);
if(strcmp(addr, "quit") == 0)
{
wait(NULL);
break;
}
}
}else if(pid==0){
while(1){
//等待3号灯的资源
P(semid,3);
//向物理内存中写入数据
fgets(addr,4096,stdin);
addr[strlen(addr)-1]='\0';
//释放2号灯的资源
V(semid,2);
if(strcmp(addr, "quit") == 0)
{
exit(EXIT_SUCCESS);
break;
}
}
}else{
perror("fork error");
return -1;
}
//取消映射
if(shmdt(addr) == -1)
{
perror("shmdt error");
return -1;
}
//删除共享内存
if(shmctl(shmid, IPC_RMID, NULL) ==-1)
{
perror("shmctl error");
return -1;
}
//删除信号灯集
del_sem(semid);
return 0;
}
运行结果: