Experiment 3 of Hangzhou Electric Operating System realizes communication between two processes by using shared memory communication mechanism of Linux

Posted by keldorn on Thu, 10 Oct 2019 00:08:46 +0200

4) Using Linux's shared memory communication mechanism to realize communication between two processes

Sender, which creates a shared memory, then waits for the user to input a string of characters through the terminal and send them to the receiver through the shared memory. Finally, it waits for the response of the receiver. After receiving the response message, it displays the received response information on the terminal screen, deletes the shared memory, and ends the running of the program. Write a receiver program, which receives messages from sender through shared memory, displays the messages on the terminal screen, and then sends a reply message "over" to sender through the shared memory (the teacher tells you that this step can be omitted), and ends the running of the program. Choose appropriate semaphore mechanism to realize mutual exclusion and synchronization of shared memory between two processes.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/shm.h>
sem_t *w;//Define written semaphores 
int main(){
	pid_t pid;
	int  shm_id,x;
	char *shm_addr;
	char *name="writer";
	char buff [256];
	//Initialize a named semaphore 
	w=sem_open(name,O_CREAT,0666,1);
	
	//The following two lines of code are used to ensure that Write's initial value is 1, because sometimes Write's initial value is not 1 during debugging. 
	//You can use these two lines of code if you need to 
	/*sem_getvalue(w,&x);
	if(x==0) sem_post(w);*/
	 
	shm_id=shmget(IPC_PRIVATE,256,0666);
	if(shm_id<0){
		perror("shmget error");
		exit(1);
	}
	pid=fork();//Create subprocesses 
	if(pid<0){//Failure to create 
		perror("fork error");
		exit(1);
	}
	else if(pid==0){//Currently running subprocesses 
		while(1){
			sem_wait(w);//Permission to apply for writing 
			//Mapping shared memory area objects to the address space of the calling process
			//Function prototype void *shmat(int shmid, const void *shmaddr, int shmflg)
			//See https://baike.baidu.com/item/shmat for the meaning of specific parameters. 
			shm_addr=shmat(shm_id,0,0);
			if(shm_addr==(void *)-1){//Mapping failure 
				perror("child shmat error");
				sem_post(w);
				exit(1);
			}
			strcpy(buff,shm_addr);//Copy information in shared memory to buff 
			printf("child receive:%s",buff );
			//Disconnect shared memory connection 
			//Function prototype int shmdt(const void *shmaddr)
			//See https://baike.baidu.com/item/shmat for the meaning of specific parameters.  
			if(shmdt(shm_addr)<0){
				perror("child shmdt");//Disconnect failed, return prompt 
				sem_post(w);//Release write permissions 
				exit(1);
			}	
			sem_post(w);
			sleep(2); 
		}
	}
	else while(1){//Currently running parent process 
		sem_wait(w); 
		printf("parent send:");
		shm_addr=shmat(shm_id,(void *)0,0);
		if(shm_addr==(void *)-1){
			perror("parent shmat error"); 
			sem_post(w);
			exit(1);
		}
		fgets(buff,256,stdin);//Read the keyboard line and enter it into buff 
		if(!strncmp(buff,"exit",4)){
			sem_post(w);
			if (shmctl(shm_id,IPC_RMID,NULL)==-1){
				perror("shmctl :IPC_ RMID");
				sem_post(w);
				exit(1);
			}
			else{
				printf("-------end--------\n");
				sem_post(w);
				exit(0);
			}
		}
		else{
			//Write buff to shared memory 
			strncpy(shm_addr,buff,strlen(buff));
			//Disconnect shared memory 
			if(shmdt(shm_addr)<0){
				perror("parent shmdt");
				sem_post(w);
				exit(1);
			}
		        sem_post(w);
			sleep(3);
		}
	}
	return 0;
}	

 

Topics: Linux