用信号量来管理临界资源(一次性只能一个进程访问的资源),由于共享内存没有阻塞,多个进程同时打开读和写会发生错误,我们可以用信号量来实现管理
实现过程:先让write写,在让read读,再让read写,最后再让write读
write.c
#include <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
union semun{
int val; /* 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 <sys/shm.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>
union semun{
int val; /* 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");
}