当前位置: 代码迷 >> 综合 >> apue 2e TELL_WAIT TELL_PARENT WAIT_PARENT TELL_CHILD WAIT_CHILD 实现
  详细解决方案

apue 2e TELL_WAIT TELL_PARENT WAIT_PARENT TELL_CHILD WAIT_CHILD 实现

热度:2   发布时间:2023-12-18 17:25:21.0

下面代码第一版的文件,第二版的文件在 lib/tellwait.c中,不用再单独下载。

默认是以信号量方式实现,但在Freebsd 9下面运行效果并不理想。参考资料2中有按管道方式实现。将 "ourhdr.h" 修改为 "apue.h"。

FreeBSD 下

命令获取

fetch http://www.yendor.com/programming/unix/apue/lib.44/tellwait.c

tellwait.c

#include	<signal.h>
#include	"apue.h"static volatile sig_atomic_t	sigflag;/* set nonzero by signal handler */
static sigset_t			newmask, oldmask, zeromask;static void
sig_usr(int signo)	/* one signal handler for SIGUSR1 and SIGUSR2 */
{sigflag = 1;return;
}void
TELL_WAIT()
{if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal(SIGINT) error");if (signal(SIGUSR2, sig_usr) == SIG_ERR)err_sys("signal(SIGQUIT) 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");
}

SVR4 和SunOS下

命令获取命令

fetch http://www.yendor.com/programming/unix/apue/lib.svr4/tellwait.c

tellwait.c

#include	<signal.h>
#include	"apue.h"static volatile sig_atomic_t	sigflag;/* set nonzero by signal handler */
static sigset_t			newmask, oldmask, zeromask;static void
sig_usr(int signo)	/* one signal handler for SIGUSR1 and SIGUSR2 */
{sigflag = 1;return;
}void
TELL_WAIT()
{if (signal(SIGUSR1, sig_usr) == SIG_ERR)err_sys("signal(SIGINT) error");if (signal(SIGUSR2, sig_usr) == SIG_ERR)err_sys("signal(SIGQUIT) 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");
}

将下载后的tellwait.c(或者apue源文件包中的 /lib/tellwait.c)拷贝至/usr/include,然后在源文件中将tellwait.c包含即可编译。

#include "tellwait.c"

参考资料:

[1]Chapter 8 Process Control.http://www.yendor.com/programming/unix/apue/ch8.html

[2]APUE 中的TELL函数.http://blog.csdn.net/born1985man/article/details/4635778

[3]《UNIX环境高级编程》程序清单8-7编译错误:TELL_WAIT, WAIT_PARENT, TELL_CHILD未定义.http://blog.csdn.net/fushaobing2010/article/details/6160204