目的
让父子进程通过共享内存来读写数据,父进程负责写,子进程负责读,确保一个进程执行,另一个进程不会执行。
代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define SEM_READ 0
#define SEM_WRITE 0
union semun
{
int val;
};
void P(int index,int semid)
{
struct sembuf sep;
sep.sem_num = index;
sep.sem_op = -1;
sep.sem_flg = 0;
semop(semid,&sep,1);
}
void V(int index,int semid)
{
struct sembuf sep;
sep.sem_num = index;
sep.sem_op = 1;
sep.sem_flg = 0;
semop(semid,&sep,1);
}
int main()
{
key_t key;
int semid;
int shmid;
pid_t pid;
char *p;
key=ftok("d.c",123);
semid=semget(key,1,0755|IPC_CREAT);
if(semid < 0)
{
perror("semget");
return -1;
}
shmid=shmget(key,128,0755|IPC_CREAT);
if(shmid < 0)
{
perror("shmget");
return -2;
}
//init semaphore
union semun myun;
//init semaphore write
myun.val = 1;
semctl(semid,SEM_WRITE,SETVAL,myun);
pid = fork();
if(pid > 0 )
{
while(1)
{
p = (char *)shmat(shmid,NULL,0);
P(SEM_WRITE,semid);
printf("please input:\n");
fgets(p,40,stdin);
V(SEM_WRITE,semid);
}
}
else if(pid == 0)
{
while(1)
{
p=(char *)shmat(shmid,NULL,0);
P(SEM_READ,semid);
printf("p===%s\n",p);
V(SEM_READ,semid);
}
}
return 0;
}
执行结果:
代码说明
通过ftok函数获取key值,通过shmget来获取共享内存,通过semget函数创建信号灯数量为1的信号灯集,或通semget函数初始化编号为0的信号灯的信号量值为1,用ftok创建父子进程,在子进程和父进程里,分别调用semat函数,使进程里地址映射到共享内存,在父、子进程里,通过PV操作,确保父进程执行写操作的时候,子进程不会执行读操作,子进程执行读操作的时候,父进程不会执行写操作。
P操作使信号量当前值-1,因为这里设置的信号量初始值为1,所以减1,信号量当前值变为0,表示当用资源,
其他进程不能获得资源,要等待执行P操作的进程,使用V操作,是信号量当前值加1,变为1,来释放资源,这
是其他进程才能获取资源。