/** Title: * Program, to achieve the following functions: The parent process to create sub-process 1 and child process 2, child process 1 to send a reliable signal to the child process 2, and transmit additional data for the child process 1 pid*2, sub-process 2 to accept a reliable signal value, and sent to the parent process, the parent process to print the values accepted. Hint: implemented with Sigqueue and sigaction **/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<errno.h>#include<sys/types.h>#include<sys/wait.h>#include<signal.h>#include<sys/shm.h>/* Analysis:* Child process 2 into the shared memory area, sub-process 1 from the shared memory area to read the PID of child process 2, to the sub-process 2 to send a signal with data **///Sub-process 2 signal installation callback functionvoidHandlerintSign, siginfo_t * info,void*p) { if(Sign = =sigrtmin) {printf ("Child Process 2 received data%d\n",info->si_value.sival_int); //send a signal to the parent process if(Sigqueue (Getppid (), sigrtmin, info->si_value)! =0) {perror ("sigqueue () Err"); return; } //Exit subprocess 2printf"Sub-process 2 quit\n"); Exit (0); }}//Parent Process Signal installation callback functionvoidHandlerf (intSign, siginfo_t * info,void*p) { if(Sign = =sigrtmin) { //Print Signal Valueprintf"the value received by the parent process is%d\n", info->si_value.sival_int); }}intMainintArgChar*args[]) { //Create a shared memory area intShmid = Shmget (Ipc_private,sizeof(int),0666); if(Shmid = =-1) {printf ("Shmget () failed!\n"); return-1; } pid_t PID=0; PID=Fork (); if(PID = =-1) {perror ("fork () Err"); return-1; } if(PID = =0) { //Sub-Process 1printf"pid=%d\n of Sub-process 1", Getpid ()); int*pid2 =NULL; //Child Process 1 is attached to the shared memory areaPid2 = (int*) Shmat (Shmid,0,0); if((int) Pid2 = =-1) {perror ("Shmat () Err"); return-1; } //wait for process 2 to write data to the shared memory area while(*pid2 = =0) { //waiting to have data in the shared memory areaSleep1); } //send a reliable signal to process 2Union Sigval v1; V1.sival_int= Getpid () *2; if(Sigqueue (*pid2, sigrtmin, v1)! =0) {perror ("sigqueue () Err"); return-1; } //Process 1 exits when the signal is sent outprintf"Sub-process 1 exit\n"); Exit (0); } PID=Fork (); if(PID = =-1) {perror ("fork () Err"); return-1; } if(PID = =0) { //Sub-process 2printf"pid=%d\n of Sub-process 2", Getpid ()); //Mounting Signal sigrtmin structSigaction Act; Act.sa_sigaction=handler; Sigemptyset (&act.sa_mask); Act.sa_flags=Sa_siginfo; if(Sigaction (Sigrtmin, &act, NULL)! =0) {printf ("sigaction () failed!\n"); return-1; } int*mypid =NULL; //Child Process 2 is attached to the shared memory areaMypid = (int*) Shmat (Shmid,0,0); if((int) Mypid = =-1) {perror ("Shmat () Err"); return-1; } //Place the PID of child process 2 into the shared memory area, manipulate the private shared memory area, and map to the system shared memory area*mypid =Getpid (); //wait for child process 1 to send itself a signal while(1) {printf ("Sub-process 2 sleep\n"); Sleep (1); } } //Parent Process//Mounting Signal sigrtmin structSigaction Act; Act.sa_sigaction=Handlerf; Sigemptyset (&act.sa_mask); Act.sa_flags=Sa_siginfo; if(Sigaction (Sigrtmin, &act, NULL)! =0) {printf ("sigaction () failed!\n"); return-1; } intret=0; //wait for child process while(1) {ret=Wait (NULL); printf ("Child process pid=%d\n", ret); if(ret==-1) { if(errno==eintr) { Continue; } Break; } } //freeing the shared memory area if(Shmctl (Shmid, Ipc_rmid, NULL)! =0) {printf ("shmctl () failed!\n"); } printf ("game is over!\n"); return 0;}/** ERROR Summary: GDB error: Shmat () err:invalid argument, meaning that the Shmat () parameter is incorrect * after a half-day analysis, I found that I did not wait child process in the parent process, directly called the Shmctl () function, the shared memory to release, So error **/
Linux Linux Program Practice XV (inter-process Communication shared Memory Edition)