#include #include #include #include #include #include int cycles = 0; pid_t child_pid; pid_t parent_pid; int main(int argc, char **argv) { struct sigaction sa; sigset_t blockem; extern void be_the_parent(), be_the_child(); extern void parent_terminate(), child_terminate(); extern void null_handler(); parent_pid = getpid(); sigemptyset(&blockem); sigaddset(&blockem, SIGUSR1); sigprocmask(SIG_BLOCK, &blockem, NULL); sigfillset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = parent_terminate; if(sigaction(SIGALRM, &sa, NULL)) { perror("sigaction SIGALARM"); exit(1); } sa.sa_handler = null_handler; if(sigaction(SIGUSR1, &sa, NULL) < 0) { perror("sigaction SIGUSR1"); exit(1); } sa.sa_handler = child_terminate; sigfillset(&sa.sa_mask); if(sigaction(SIGUSR2, &sa, NULL)) { perror("sigaction SIGUSR2"); exit(1); } switch(child_pid = fork()) { case -1: perror("fork"); exit(2); break; case 0: be_the_child(); exit(0); break; default: be_the_parent(); exit(0); break; } fprintf(stderr,"Unexpected exit from program!\n"); exit(3); } void be_the_parent() { sigset_t sigset; double x = 0., y = 0.; double z = 1.; sigemptyset(&sigset); alarm(5); z = 3.; y = 4.; while(1) { if(kill(child_pid, SIGUSR1) < 0) { perror("kill"); return; } y = (double)(65536 * ((double) rand() / (double) RAND_MAX)); if(cycles & 1) { x = log(y); } else { x = log(z / y); } cycles++; sigsuspend(&sigset); } } void be_the_child() { sigset_t sigset; double x = 0., y = 0.; double z = 1.; sigemptyset(&sigset); z = 3.; y = 4.; while(1) { sigsuspend(&sigset); if(kill(parent_pid, SIGUSR1) < 0) { perror("kill"); return; } y = (double)(65536 * ((double) rand() / (double) RAND_MAX)); if(cycles & 1) { x = log(y); } else { x = log(z / y); } cycles++; } } void null_handler() { ; } void parent_terminate() { printf("%d log(x) calculations using math library made.\n", cycles); kill(child_pid, SIGUSR2); wait(NULL); exit(0); } void child_terminate() { exit(0); }