In this section, the Tell_wait and Tell_parent,tell_child in the book do not figure out exactly how the synchronization mechanism is implemented.
proc/tellwait1.c 8-6#include "apue.h" static void Charatatime (const char *); int main (void) { pid_t pid; if (PID = fork ()) < 0) { Err_sys ("fork Error"); } else if (PID = = 0) { charatatime ("Output from child\n"); } else { charatatime ("Output from parent\n"); } return 0;} static void Charatatime (const char* str) { const char* ptr; int C; Setbuf (stdout, NULL); /* Set unbuffered * /for (ptr = str; (c = *ptr++)! = 0; { PUTC (c, stdout); }}
Lib/tellwait.c#include "apue.h" static volatile sig_atomic_t Sigflag; /* Set nonzero by sig Handler */static sigset_t Newmask, Oldmask, zeromask;static void sig_usr (int signo)/* One signal Han Dler for SIGUSR1 and SIGUSR2 */{sigflag = 1;} void tell_wait (void) {if (Signal (SIGUSR1, sig_usr) = = Sig_err) {Err_sys ("Signal (SIGUSR1) error"); } if (Signal (SIGUSR2, sig_usr) = = Sig_err) {Err_sys ("Signal (SIGUSR2) error"); } sigemptyset (&zeromask); Sigemptyset (&newmask); Sigaddset (&newmask, SIGUSR1); Sigaddset (&newmask, SIGUSR2); /* * Block SIGUSR1 and SIGUSR2, and save current signal mask. */if (Sigprocmask (Sig_block, &newmask, &oldmask) < 0) {Err_sys ("Sig_block error"); }}voidtell_parent (pid_t pid) {Kill (PID, SIGUSR2);/* Tell PARENT we ' re do */}void wait_parent (void) {while (Sigflag = = 0) {sigsuspend (&zeromask);/* and wait for parent */}sigflag = 0;/* * Reset signal mask to orIginal value. */if (Sigprocmask (Sig_setmask, &oldmask, NULL) < 0) {Err_sys ("Sig_setmask error"); }}void tell_child (pid_t pid) {Kill (PID, SIGUSR1);/* Tell child we ' re do */}void wait_child (void) {while (Sigflag = = 0) sigs Uspend (&zeromask);/* and wait for child */sigflag = 0;/* * Reset signal mask to original value. */if (Sigprocmask (Sig_setmask, &oldmask, NULL) < 0) Err_sys ("Sig_setmask error");}
proc/tellwait2.c 8-7#include "apue.h" static void Charatatime (const char*); int main () { pid_t pid; Tell_wait (); if (PID = fork ()) < 0) { Err_sys ("fork Error"); } else if (PID = = 0) { wait_parent ();/* PARENT goes First * /charatatime ("Output from child\n"); } else { charatatime ("Output from parent\n"); Tell_child (PID); } return 0;} static void Charatatime (const char* str) { const char* ptr; int C; Setbuf (stdout, NULL); /* Set unbuffered * /for (ptr = str; (c = *ptr++)! = 0; { PUTC (c, stdout); }}
Proc/tellwait3.c#include "apue.h" static void Charatatime (const char*); int main () { pid_t pid; Tell_wait (); if (PID = fork ()) < 0) { Err_sys ("fork Error"); } else if (PID = = 0) { charatatime ("Output from child\n"); Tell_parent (Getppid ()); /* Parent goes First * /} else { wait_child (); Charatatime ("Output from parent\n"); } return 0;} static void Charatatime (const char* str) { const char* ptr; int C; Setbuf (stdout, NULL); /* Set unbuffered * /for (ptr = str; (c = *ptr++)! = 0; { PUTC (c, stdout); }}
UNIX Environment Advanced programming 8.9 competitive conditions