APUE2e之Exercise 10.6 Solution C

来源:互联网 发布:知天下图吧 编辑:程序博客网 时间:2024/06/06 07:08

Using Standard I/O Library to read and write the file. Rather than using signal function, I used sigaction. Thus don’t need to call TELL_WAIT in the for body.


/**    * apue-chap10: exercise10-6c.c * * Description: Standard I/O Library + sigaction * * Created On: Feb 16, 2012  * * @author: Huang Zhu * * @email: zhuhuang.zp@gmail.com */ #include <apueerr.h>#include <signal.h>#include <stdio.h>#include <fcntl.h> #define __USE_POSIX1993091 static volatile sig_atomic_t sigflag;static sigset_t newmask, oldmask, zeromask; struct sigaction act, oact1, oact2; static void sig_usr(int signo){sigflag = 1;} void TELL_WAIT(void){act.sa_handler = sig_usr;sigemptyset(&act.sa_mask);act.sa_flags = 0; if(sigaction(SIGUSR1, &act, &oact1) < 0)err_sys("sigaction SIGUSR1 error"); if(sigaction(SIGUSR2, &act, &oact2) < 0)err_sys("sigaction SIGUSR2 error"); sigemptyset(&zeromask);sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);sigaddset(&newmask, SIGUSR2); //block SIGUSR1 and SIGUSR2, and save current signal maskif(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)perror("SIG_BLOCK error");} void TELL_PARENT(pid_t pid){kill(pid, SIGUSR2);} void TELL_CHILD(pid_t pid){kill(pid, SIGUSR1);} void WAIT_PARENT(void){while(sigflag == 0)sigsuspend(&zeromask);  //set mask and sleep and waitsigflag = 0; if(sigprocmask(SIG_SETMASK, &oldmask,  NULL) < 0)perror("SIG_SETMASK error");} void WAIT_CHILD(void){while(sigflag == 0)sigsuspend(&zeromask);  //set mask and sleep and waitsigflag = 0; if(sigprocmask(SIG_SETMASK, &oldmask,  NULL) < 0)perror("SIG_SETMASK error");} int main(void){int fd, pid, ppid, counter, round = 5;FILE* fp;char *filename = "counter.file";int i, j; if((fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)err_sys("open error"); if((fp = fdopen(fd, "r+")) == NULL )err_sys("fdopen error"); if(fputc(0, fp) != EOF){printf("Writing initial value of the counter: 0\n");fflush(fp); //if fflush is not used, the change of counter cannot be seen instantly by other readers.} if(ferror(fp))err_sys("fputc error"); TELL_WAIT(); if((pid = fork()) < 0){err_sys("fork error");}else if(pid == 0){ //childppid = getppid(); for(i = 0;  i < round; i++){printf("\nChild: round %d\n", i+1);counter = -1; rewind(fp);counter = fgetc(fp);printf("Child: read counter from the file: %d\n", counter); counter++;printf("Child: increase counter to: %d\n", counter); rewind(fp);if(fputc(counter, fp) != EOF){printf("Child: Write counter to the file: %d\n", counter);fflush(fp);}if(ferror(fp))err_sys("Child: fputc error"); TELL_PARENT(ppid); WAIT_PARENT();} counter = -1;rewind(fp);counter = fgetc(fp);printf("\nChild: read counter from the file: %d\n", counter); exit(0);}else{ //parentfor(j = 0; j < round; j++){WAIT_CHILD();printf("\nParent: round %d\n", j+1);counter = -1; rewind(fp);counter = fgetc(fp);printf("Parent: read counter from the file: %d\n", counter); counter++;printf("Parent: increase counter to: %d\n", counter); rewind(fp);if(fputc(counter, fp) != EOF){printf("Parent: Write counter to the file: %d\n", counter);fflush(fp);}if(ferror(fp))err_sys("Parent: fputc error"); TELL_CHILD(pid);}} fclose(fp);close(fd);return 0;}


原创粉丝点击