此程序实现没有亲缘关系的两个进程间通过共享内存进行数据通信。
同时,使用信号量保证两个进程的读写同步:发送方在写共享内存时,接收方不能读数据;接收方在读数据时,发送方不能写数据。
1、fork创建子进程
2、使用二元信号量,同步读写端
fork_shm.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include"send_recv.h"
int main(void)
{
printf("fork test!\n");
pid_t pid;
if((pid=fork())==-1)
printf("fork error");
else if(pid==0)
{
printf("in the child process\n");
printf("the father process's ppid is %d\n",getppid());
fork_recv();
}
else
{
//sleep(1);
printf("in the parent process\n");
printf("the son process's pid is %d\n",getpid());
fork_send();
}
return 0;
}
send_recv.c
#include"fork_recv.c"
#include"fork_send.c"
int fork_recv();
int fork_send();
fork_send.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
int fork_send()
{
int running=1;
int shid;
int semid;
int value;
void *sharem=NULL;
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_flg = SEM_UNDO;
if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1)
{
perror("semget");
exit(EXIT_FAILURE);
}
if (semctl(semid, 0, SETVAL, 0) == -1)
{
printf("sem init error");
if(semctl(semid,0,IPC_RMID,0)!=0)
{
perror("semctl");
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
shid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);
if(shid==-1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
sharem=shmat(shid,NULL,0);
if(sharem==NULL)
{
perror("shmat");
exit(EXIT_FAILURE);
}
while(running)
{
if((value=semctl( semid, 0, GETVAL ))==0)
{
printf("write data operate\n");
printf("please input something:\n");
scanf("%s",sharem);
sem_b.sem_op = 1;
if (semop(semid, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_p failed\n");
exit(EXIT_FAILURE);
}
}
if(strcmp(sharem,"end")==0)
running--;
}
shmdt(sharem);
return 0;
}
fork_recv.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
int fork_recv()
{
int running=1;
char *shm_p=NULL;
int shmid;
int semid;
int value;
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_flg = SEM_UNDO;
if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1)
{
perror("semget");
exit(EXIT_FAILURE);
}
shmid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);
if(shmid==-1)
{
perror("shmget");
exit(EXIT_FAILURE);
}
shm_p=shmat(shmid,NULL,0);
if(shm_p==NULL)
{
perror("shmat");
exit(EXIT_FAILURE);
}
while(running)
{
if((value=semctl( semid, 0, GETVAL ))==1)
{
printf("read data operate\n");
sem_b.sem_op = -1;
if (semop(semid, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore_p failed\n");
exit(EXIT_FAILURE);
}
printf("%s\n",shm_p);
}
if(strcmp(shm_p,"end")==0)
running--;
}
shmdt(shm_p);
if(shmctl(shmid,IPC_RMID,0)!=0)
{
perror("shmctl");
exit(EXIT_FAILURE);
}
if(semctl(semid,0,IPC_RMID,0)!=0)
{
perror("semctl");
exit(EXIT_FAILURE);
}
return 0;
}