io+day8
#ifndef __SEM2 #define __SEM3 4 //声明一个创>5 int init_sem(6 7 //声明一个p操8 int P(int sem9 10 //声明一个v操11 int W(int sem12 13 //声明一个删>14 int del_sem(i15 16 #endif
1 #include <myhead.h> 2 union semun {3 int val; /* Value for SETVAL */4 struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */5 unsigned short *array; /* Array for GETALL, SETALL */6 struct seminfo *__buf; /* Buffer for IPC_INFO7 (Linux-specific) */8 };9 //信号灯集里每个信号灯的初始化10 int sem_value(int semid,int semno,int semvalue)11 {12 union semun us;13 us.val=semvalue;14 if(semctl(semid,semno,SETVAL,us)==-1)15 {16 perror("semctr");17 return -1;18 }19 return 0;20 }21 //创建信号灯集并初始化函数22 int init_sem(int semnum)23 {24 //1.创建一个key钥匙25 key_t key;26 if((key=ftok("/",'t'))==-1)27 {28 perror("ftok");29 return -1;30 }31 //2.创建一个信号灯集32 int semid;33 if((semid=semget(key,semnum,IPC_CREAT|IPC_EXCL|0664))==-1)34 {35 if(errno==EEXIST)36 {37 //防止多进程同时调用时多次初始化38 semid=semget(key,semnum,IPC_CREAT|0664);39 return semid;40 }41 perror("semget");42 return -1;43 }44 //3.信号灯集初始化45 for(int i=0;i<semnum;i++)46 {47 if(i==0)48 {49 //参数1:id50 //参数2:初始化的信号灯编号51 //参数3:初始化的信号灯的value值52 sem_value(semid,i,1);53 }54 else55 {56 sem_value(semid,i,0);57 }58 }59 return semid;60 }61 62 //p操作函数63 int P(int semid,int semno)64 {65 struct sembuf buf;66 buf.sem_num=semno;//灯集里灯编号67 buf.sem_op=1; //释放资源68 buf.sem_flg=0; //阻塞69 if(semop(semid,&buf,1)==-1)70 {71 perror("semop");72 return -1;73 }74 return 0;75 76 }77 //w操作函数78 int W(int semid,int semno)79 {80 struct sembuf buf;81 buf.sem_num=semno;//灯集里灯编号82 buf.sem_op=-1; //申请资源83 buf.sem_flg=0; //阻塞84 if(semop(semid,&buf,1)==-1)85 {86 perror("semop");87 return -1;88 }89 return 0;90 }91 92 //删除信号灯的函数93 int del_sem(int semid)94 {95 if(semctl(semid,0,IPC_RMID,0)==-1)96 {97 perror("semctl");98 return -1;99 }
100 return 0;
101 }
1 #include <myhead.h>2 #include "sem.h"3 int main(int argc, const char *argv[])4 {5 //创建钥匙6 key_t key=-1;7 if((key=ftok("/",'c'))==-1)8 {9 perror("ftok");10 return -1;11 }12 //创建共享享内存13 int shmid; 14 if((shmid=shmget(key,4096,IPC_CREAT|0664))=15 {16 perror("shmget");17 return -1;18 } 19 //映射到用户空间20 char *adder;21 if((adder=shmat(shmid,NULL,0))==(void *)-1)22 {23 perror("shmat");24 return -1;25 } 26 //创建一个信号灯集27 int semid;28 semid=init_sem(4);29 //创建父子进程30 pid_t pid;31 pid=fork();32 if(pid<0)33 { 34 perror("fork");35 return -1;36 } 37 else if(pid>0)38 { 39 //父进程40 while(1)41 {42 //等待0信号资源43 W(semid,0);44 fgets(adder,4096,stdin);45 adder[strlen(adder)-1]='\0';46 //释放1信号资源47 P(semid,1);48 if(strcmp(adder,"quit")==0)49 {50 break;51 } 52 }53 wait(NULL);54 } 55 else 56 { 57 //子进程58 while(1)59 { 60 //等待3信号资源61 W(semid,3);62 //房子里面拿东西63 printf("共享内存数据:%s\n",adder);64 //释放2信号资源65 P(semid,2);66 if(strcmp(adder,"quit")==0)67 {68 break;69 } 70 } 71 exit(EXIT_SUCCESS);72 } 73 //取消链接74 shmdt(adder);75 return 0;76 }