This example is a signal-based synchronization mechanism that enables parent-child processes to change the values in a file in turn.
Taticvolatilesig_atomic_t Sigflag;Staticsigset_t Newmask,oldmask,zeromask;Static voidSIG_USR (intSigno) {Sigflag=1;}voidTell_wait (void){ if(Signal (SIGUSR1,SIG_USR) = =sig_err) perror ("Signal Error"); if(Signal (SIGUSR2,SIG_USR) = =sig_err) perror ("Signal Error"); Sigemptyset (&zeromask); Sigemptyset (&newmask); Sigaddset (&NEWMASK,SIGUSR1); Sigaddset (&NEWMASK,SIGUSR2); if(Sigprocmask (Sig_block,&newmask,&oldmask) <0) perror ("Sig_block Error");}voidtell_parent (pid_t pid) {Kill (PID,SIGUSR2);}voidWait_parent (void){ while(sigflag==0) Sigsuspend (&zeromask); Sigflag=0; if(Sigprocmask (sig_setmask,&oldmask,null)) Perror ("Sig_setmask Error");}voidtell_child (pid_t pid) {Kill (PID,SIGUSR1);}voidWait_child (void){ while(sigflag==0) Sigsuspend (&zeromask); Sigflag=0; if(Sigprocmask (sig_setmask,&oldmask,null)) Perror ("Sig_setmask Error");}
The above is the code implementation of the parent-child process via signal synchronization
That's what I wrote first, the code.
intMain () {intFD; pid_t pid; Charbuf[3]; intNumber=0; intLen; buf[0]='0'; buf[1]=' /'; if((Fd=open ("file.txt", o_rdwr| O_creat| o_trunc| O_sync)) <0) perror ("Open File Error"); if(Write (Fd,buf,2) <0) perror ("Write Error"); Tell_wait (); if((Pid=fork ()) <0) {perror ("Fork Error"); }Else if(PID = =0) { for(;;) {wait_parent (); Lseek (Fd,seek_set,0); if(Len=read (Fd,buf,Ten)) <0) perror ("Read Error"); number=atoi (BUF); printf ("Child number %d\n", number); number++; memset (BUF,0,sizeof(BUF)); sprintf (BUF,"%d", number); Buf[strlen (BUF)]=' /'; if(Open ("file.txt", o_rdwr| O_creat| o_trunc| O_sync) <0) perror ("Open ERRPR");//Lseek (fd,seek_set,0); if(Write (Fd,buf,2) <0) perror ("Write Error"); Sleep (2); Tell_parent (Getppid ()); } }Else { for(;;) {Lseek (Fd,seek_set,0); if(Len=read (Fd,buf,Ten)) <0) perror ("Read Error"); number=atoi (BUF); printf ("Parent Number:%d\n", number); number++; memset (BUF,0,sizeof(BUF)); sprintf (BUF,"%d", number); if(Open ("file.txt", o_wronly| O_creat| O_trunc) <0)//perror ("Open Errpr");//Lseek (fd,seek_set,0); if(Write (Fd,buf,2) <0) perror ("Write Error"); Sleep (2); Tell_child (PID); Wait_child (); }} exit (0);}
Start by creating a file that writes 0 characters to the file. After the parent process reads the characters in the file, the file is emptied, and the characters are converted to a post-shaping and then written file. The child process does the same thing as the parent process. But the result is this.
00 1 122 3
The data that the child process reads is not the data that the parent process writes, and it seems that the parent-child process is independent of the file, which does not conform to the rules that parent-child processes share the same file table entry. I've been watching it for so long,
So I added a delay before the parent process emptied the file, looked at the contents of the file, and found a normal write. After the write operation is emptied, the contents of the file discovery file are empty.
Sleep (4);
if (Open ("file.txt", o_wronly| O_creat| O_trunc) <0)
So debugging a bit to see the value of the unprecedented buf, found no problem
the sprintf (buf,"%d", number);(gdb) s Sleep (3);( GDB) P buf$2"1\000"
Then, when you run to the second sleep function, you view the contents of the file and find the file empty.
So I guess the problem is that I emptied the file through the open function. (I don't know why this is, I hope someone can guide me)
So I changed a way to overwrite the original data directly with each write data, instead of truncating the file length to 0, to implement
Else if(PID = =0) { for(;;) {wait_parent (); Lseek (Fd,seek_set,0); if(Len=read (Fd,buf,Ten)) <0) perror ("Read Error"); number=atoi (BUF); printf ("Child number %d\n", number); number++; memset (BUF,0,sizeof(BUF)); sprintf (BUF,"%d", number); Buf[strlen (BUF)]=' /';//if (open ("file.txt", o_rdwr| O_creat| o_trunc| O_sync) <0)//perror ("Open Errpr");Lseek (Fd,seek_set,0); if(Write (Fd,buf,2) <0) perror ("Write Error"); Sleep (2); Tell_parent (Getppid ()); } }Else { for(;;) {Lseek (Fd,seek_set,0); if(Len=read (Fd,buf,Ten)) <0) perror ("Read Error"); number=atoi (BUF); printf ("Parent Number:%d\n", number); number++; memset (BUF,0,sizeof(BUF)); sprintf (BUF,"%d", number); //if (open ("file.txt", o_wronly| O_creat| O_trunc) <0)//perror ("Open Errpr");Lseek (Fd,seek_set,0); if(Write (Fd,buf,2) <0) perror ("Write Error"); Sleep (2); Tell_child (PID); Wait_child (); } }
01 2 345
Linux implements parent-child processes change the value of a file in turn