首页 > 其他 > 详细

UNIX环境高级编程8.9竞争条件

时间:2015-02-06 14:35:20      阅读:269      评论:0      收藏:0      [点我收藏+]

这一节,书中的TELL_WAIT与TELL_PARENT,TELL_CHILD没有弄清楚,到底是如何实现的同步机制。

技术分享

技术分享

技术分享

 

// 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 handler 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");
    }
}

void
TELL_PARENT(pid_t pid)
{
	kill(pid, SIGUSR2);		/* tell parent we‘re done */
}

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 done */
}

void WAIT_CHILD(void)
{
	while (sigflag == 0)
		sigsuspend(&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环境高级编程8.9竞争条件

原文:http://www.cnblogs.com/sunyongjie1984/p/4276923.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!