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