使用信号量灯集同步三个进程操作共享内存打印ABC
head.h
#ifndef __SEM_H__
#define __SEM_H__//创建信号灯集并初始化
int create_sem(int semcount);//申请资源 P操作
int P(int semid,int semno);//释放资源 V操作
int V(int semid,int semno);//删除信号灯集
int delete_sem(int semid);#endif
test.c
#include<my_head.h>
union semun
{int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf;
};//初始化信号灯集函数
int init_sem(int semid,int semno)
{union semun us;printf("请输入第%d号灯的初始值:",semno);scanf("%d",&us.val);getchar();if(semctl(semid,semno,SETVAL,us) == -1){perror("init_sem error");return -1;}return 0;
}//创建信号灯集并初始化
int create_sem(int semcount)
{key_t key = ftok("/",520);if(key == -1){perror("ftok error");return -1;}int semid = semget(key,semcount,IPC_CREAT|IPC_EXCL|0666);if(semid == -1){if(errno == EEXIST){semid = semget(key,semcount,IPC_CREAT);return semid;}perror("semget error");return -1;}for(int i=0;i<semcount;i++){init_sem(semid,i);}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 delete_sem(int semid)
{if(semctl(semid,0,IPC_RMID) == -1){perror("delete_sem error");return -1;}return 0;
}
A.c
#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"int main(int argc, const char *argv[])
{//创建信号灯集并初始化int semid = create_sem(3);//创建key值key_t key = ftok("/",1314);if(key == -1){perror("ftok");return -1;}//用key值创建一个共享内存,返回shmidint shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);if(shmid == -1){perror("shmget error");return -1;}//映射共享内存到用户空间char *addr = shmat(shmid,NULL,0);if(addr == (void *)-1){perror("shmat error");return -1;}//使用共享内存int count = 5;while(count -- ){//先打印一个Aputs("A");//p操作申请0号灯P(semid,0);//存放数据Bstrcpy(addr,"B");//v操作释放1号灯V(semid,1);}//取消共享内存映射if(shmdt(addr) == -1){perror("shmdt error");return -1;}return 0;
}
B.c
#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"int main(int argc, const char *argv[])
{//创建信号灯集并初始化int semid = create_sem(3);//创建key值key_t key = ftok("/",1314);if(key == -1){perror("ftok");return -1;}//用key值创建一个共享内存,返回shmidint shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);if(shmid == -1){perror("shmget error");return -1;}//映射共享内存到用户空间char *addr = shmat(shmid,NULL,0);if(addr == (void *)-1){perror("shmat error");return -1;}//使用共享内存int count = 5;while(count -- ){//p操作申请1号灯P(semid,1);//打印数据Bprintf("%s\n",addr);strcpy(addr,"C");//v操作释放2号灯V(semid,2);}//取消共享内存映射if(shmdt(addr) == -1){perror("shmdt error");return -1;}return 0;
}
C.c
#include<my_head.h>
#define PAGE_SIZE 4096
#include "head.h"int main(int argc, const char *argv[])
{//创建信号灯集并初始化int semid = create_sem(3);//创建key值key_t key = ftok("/",1314);if(key == -1){perror("ftok");return -1;}//用key值创建一个共享内存,返回shmidint shmid = shmget(key,PAGE_SIZE,IPC_CREAT|0666);if(shmid == -1){perror("shmget error");return -1;}//映射共享内存到用户空间char *addr = shmat(shmid,NULL,0);if(addr == (void *)-1){perror("shmat error");return -1;}//使用共享内存int count = 5;while(count -- ){//p操作申请2号灯P(semid,2);//打印数据Cprintf("%s\n",addr);//存放数据Bstrcpy(addr,"C");//v操作释放0号灯V(semid,0);}//取消共享内存映射if(shmdt(addr) == -1){perror("shmdt error");return -1;}//删除共享内存if(shmctl(shmid,IPC_RMID,NULL) == -1){perror("shmctl error");return -1;}//删除信号灯集delete_sem(semid);return 0;
}