APUE课后习题10.6练习代码

来源:互联网 发布:合同翻译的软件 编辑:程序博客网 时间:2024/04/29 21:35
10.6主要实现父子进程对一个文件进行同步读写,要求分别父子进程交替对文件中的变量加1后再写入文件中。

主要代码如下:

#include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <string.h>#include <sys/stat.h>#include <sys/shm.h>#include "sync.h"#define BUF_SIZE 100static volatile sig_atomic_t sigflag;//static long last_off=0;void int2chars(char* chars, int count, char* cat){int b=0, flag = count;do{flag /= 10;b++;}while(flag);chars[b--] = '\0';while(b>=0){chars[b--] = count%10 + '0';count /= 10;}strcat(chars, cat);return ;}int chars2int(char* chars){int count = 0, flag = 1;int i = strlen(chars) - 1;while(i >= 0){count += (chars[i] - '0') * flag;flag *= 10;i--;}return count;}int main(int argc, char *argv[]){FILE *fp;pid_t pid;int count = 0, shmid;char buf[1024] = "";long *lastoffptr;shmid=shmget(IPC_PRIVATE, BUF_SIZE, IPC_CREAT|0666);if(shmid == -1){printf("Shared Memory Created error...\n");exit(-127);}lastoffptr = shmat(shmid, NULL, 0);if((fp = fopen("tt.txt", "w+")) < 0){perror("open error or write error!");exit(-1);}fprintf(fp, "0\ttest\n");fflush(fp);TELL_WAIT();alarm(2);if((pid = fork()) > 0)//parent{while(1){WAIT_CHILD();printf("the current ftell=%ld\n", ftell(fp));fseek(fp, *lastoffptr, SEEK_SET);fscanf(fp, "%d\t%s\n", &count, buf);printf("parent read from the file count=%d.\n", count);*lastoffptr = ftell(fp);fprintf(fp,"%d\t%s\n", count+1, "parent");fflush(fp);TELL_CHILD(pid);}}else //child{while(1){fseek(fp, *lastoffptr, SEEK_SET);fscanf(fp, "%d\t%s\n", &count, buf);printf("child read from the file count=%d.\n", count);*lastoffptr = ftell(fp);if(fprintf(fp,"%d\t%s\n", count+1, "child")<0){printf("child write error\n");}fflush(fp);TELL_PARENT(getppid());WAIT_PARENT();}}fclose(fp);return 0;}

父子进程之间实现信号同步代码,并包含在头文件”sync.h“中:

#include <sys/types.h>#include <signal.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>static volatile sig_atomic_t sigflag;static sigset_t newmask, oldmask, zeromask;//one signal handler for SIGUSR1 and SIGUSR2static void sig_usr(int signo){sigflag = 1;}void TELL_WAIT(void){if(signal(SIGUSR1, sig_usr) == SIG_ERR){perror("signal(SIGUSR1) error");exit(-1);}if(signal(SIGUSR2, sig_usr) == SIG_ERR){perror("signal(SIGUSR2) error");exit(-2);}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");exit(-3);}}void TELL_PARENT(pid_t pid){kill(pid, SIGUSR2);}void WAIT_PARENT(void){while(sigflag == 0){sigsuspend(&zeromask);}sigflag = 0;if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){perror("SIG_SETMASK error");exit(-4);}}void TELL_CHILD(pid_t pid){kill(pid, SIGUSR1);}void WAIT_CHILD(void){while(sigflag == 0){sigsuspend(&zeromask);}sigflag = 0;if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){perror("SIG_SETMASK error");exit(-5);}}


0 0
原创粉丝点击