apue习题10.6

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>

static volatile sig_atomic_t sigflag; /* sig_atomic_t:写此种变量时不会被中断 */
static sigset_t newmask, oldmask, zeromask;

static 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(1);
    }
    sigemptyset(&zeromask);
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGUSR1);
    sigaddset(&newmask, SIGUSR2);

    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {
        perror("SIG_BLOCK error");
        exit(1);
    }
}

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(1);
    }
}

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(1);
    }
}

int main(void)
{
    pid_t pid;
    FILE *fp;
    int fd;
    int i = 0;
    char *child = "in child\n";
    char *parent = "in parent\n";

    if ((fp = fopen("tmp", "a")) == NULL) {
        perror("fopen error");
        exit(1);
    }

    fd = fileno(fp);
    /* if (write(fd, pi, 1) != 1) { */
    /*     perror("write error"); */
    /*     exit(1); */
    /* } */
    fprintf(fp, "%d\n", i);
    fflush(fp);

    TELL_WAIT();
    if ((pid = fork()) < 0) {    /* pid = fork()要用括号括起来 */
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        while (i < 100) {
            WAIT_PARENT();
            /* if (write(fd, pi, 1) != 1) { */
            /*     perror("write error"); */
            /*     exit(1); */
            /* } */
            i += 2;
            fprintf(fp, "%d\t", i);
            fflush(fp);

            write(fd, child, strlen(child));   
            TELL_PARENT(getppid());
        }
    } else {
        i++;
        while (i < 100) {
            /* if (write(fd, pi, 1) != 1) { */
            /*     perror("write error"); */
            /*     exit(1); */
            /* } */
            
            fprintf(fp, "%d\t", i);
            fflush(fp);
            i += 2;
            write(fd, parent, strlen(parent));
            TELL_CHILD(pid);
            WAIT_CHILD();
        }
    }

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值