用信号量来管理临界资源(一次性只能一个进程访问的资源),由于共享内存没有阻塞,多个进程同时打开读和写会发生错误,我们可以用信号量来实现管理

实现过程:先让write写,在让read读,再让read写,最后再让write读

write.c

#include #include #include #include #include #include #include #include #include #include #include union semun{ intval;/* Value for SETVAL */ struct semid_ds *buf;/* Buffer for IPC_STAT, IPC_SET */ unsigned short*array;/* Array for GETALL, SETALL */ struct seminfo*__buf;/* Buffer for IPC_INFO (Linux-specific) */ };void pC(int semid,int num){struct sembuf p;p.sem_num = num;//第几个灯p.sem_op = -1;p.sem_flg = SEM_UNDO;semop(semid,&p,1);}void vC(int semid,int num){struct sembuf v;v.sem_num = num;//第几个灯v.sem_op = 1;v.sem_flg = SEM_UNDO;semop(semid,&v,1);}void main(){int shmid;int semid;int key1;int key2;char *tmp = (char *)malloc(sizeof(char)*1025);key1 = ftok(".",1);key2 = ftok(".",2);shmid = shmget(key1,1024,IPC_CREAT|0600);//创建共享内存semid = semget(key2,2,IPC_CREAT|0600);//创建两个灯union semun set1;set1.val = 1;//第一个灯锁还在semctl(semid,0,SETVAL,set1);//初始化第一个灯union semun set2;set1.val = 0;//第二个灯锁不在semctl(semid,1,SETVAL,set2);//初始化第二个灯pC(semid,0);//获取第一个灯tmp = (char *)shmat(shmid,0,0);strcpy(tmp,"li jian hua");printf("write succeed!\n");shmdt(tmp);vC(semid,1);//释放第二个灯pC(semid,0);//等待第一个灯tmp = (char *)shmat(shmid,0,0);printf("read:%s\n",tmp);shmdt(tmp);vC(semid,1);//释放第二个灯shmctl(shmid,IPC_RMID,0);semctl(semid,0,IPC_RMID);printf("end...\n");}

read.c

#include #include #include #include #include #include #include #include #include #include #include union semun{ intval;/* Value for SETVAL */ struct semid_ds *buf;/* Buffer for IPC_STAT, IPC_SET */ unsigned short*array;/* Array for GETALL, SETALL */ struct seminfo*__buf;/* Buffer for IPC_INFO (Linux-specific) */ };void pC(int semid,int num){struct sembuf p;p.sem_num = num;//第几个灯p.sem_op = -1;p.sem_flg = SEM_UNDO;semop(semid,&p,1);}void vC(int semid,int num){struct sembuf v;v.sem_num = num;//第几个灯v.sem_op = 1;v.sem_flg = SEM_UNDO;semop(semid,&v,1);}void main(){int shmid;int semid;int key1;int key2;char *tmp = (char *)malloc(sizeof(char)*1025);key1 = ftok(".",1);key2 = ftok(".",2);shmid = shmget(key1,1024,IPC_CREAT|0600);//创建共享内存semid = semget(key2,2,IPC_CREAT|0600);//创建两个灯union semun set1;set1.val = 1;//第一个灯锁还在semctl(semid,0,SETVAL,set1);//初始化第一个灯union semun set2;set1.val = 0;//第二个灯锁不在semctl(semid,1,SETVAL,set2);//初始化第二个灯pC(semid,1);//获取第二个灯tmp = (char *)shmat(shmid,0,0);printf("read:%s\n",tmp);shmdt(tmp);tmp = (char *)shmat(shmid,0,0);printf("write succeed!\n");shmdt(tmp);pC(semid,0);//释放第一灯pC(semid,1);//获取第二个灯shmctl(shmid,IPC_RMID,0);semctl(semid,1,IPC_RMID);printf("end...\n");}