linux下多进程+信号量+共享内存编程

此程序实现没有亲缘关系的两个进程间通过共享内存进行数据通信。

同时,使用信号量保证两个进程的读写同步:发送方在写共享内存时,接收方不能读数据;接收方在读数据时,发送方不能写数据。

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;
}


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。