
在LInux下怎么样进行父子进程同步
1个回答
展开全部
/*
* 使用信号实现父子进程之间的同步
*
* TELL_WAIT(): set things up for TELL_xxx & WAIT_xxx
* TELL_PARENT(): tell parent we are done
* WAIT_PARENT(): wait for parent
* TELL_CHILD(): tell child we are done
* WAIT_CHILD(): wait for child
*
* SIGUSR1: the signal parent sends to child
* SIGUSR2: the signal child sends to parent
*/
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
static volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
/* signal handler for SIGUSR1 and SIGUSR2 */
static void sig_usr(int signo)
{
sigflag = 1;
return;
}
void TELL_WAIT()
{
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("signal SIGUSR1 error\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("signal SIGUSR2 error\n");
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)
printf("SIG_BLOCK error\n");
}
void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we are done */
}
void WAIT_PARENT()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1);
}
void WAIT_CHILD()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void do_task(char *task_str)
{
printf("%s\n", task_str);
}
/* parent goes first program */
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
WAIT_PARENT();
do_task("child task\n");
}
else {
do_task("parent task\n");
TELL_CHILD(pid);
}
return 0;
}
/* child goes first program*/
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
do_task("child task\n");
TELL_PARENT(getppid());
}
else {
WAIT_CHILD();
do_task("parent task\n");
}
return 0;
}
/*
* 使用管道实现父子进程同步
*
* 父进程在调用TELL_CHILD 时经由上一个管道写一个字符p,子进程在
* 调用TELL_PARENT时,经由下一个管道写一个字符c。相应的WAIT_XXX
* 函数调用read读一个字符,没有读到字符时阻塞(睡眠等待)。
*
*/
static int pfd1[2], pfd[2];
void TELL_WAIT()
{
if(pipe(pfd1) < 0 || pipe(pfd2) < 0)
printf("pipe error\n");
}
void TELL_PARENT(pid_t pid)
{
if(write(pfd2[1], "c", 1) != 1)
printf("write error\n");
}
void WAIT_PARENT()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'p')
printf("WAIT_PARENT: incorrect data\n");
}
void TELL_CHILD(pid_t pid)
{
if(write(pfd1[1], "p", 1) != 1)
printf("write error\n");
}
void WAIT_CHILD()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'c')
printf("WAIT_CHILD: incorrect data\n");
}
* 使用信号实现父子进程之间的同步
*
* TELL_WAIT(): set things up for TELL_xxx & WAIT_xxx
* TELL_PARENT(): tell parent we are done
* WAIT_PARENT(): wait for parent
* TELL_CHILD(): tell child we are done
* WAIT_CHILD(): wait for child
*
* SIGUSR1: the signal parent sends to child
* SIGUSR2: the signal child sends to parent
*/
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
static volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
/* signal handler for SIGUSR1 and SIGUSR2 */
static void sig_usr(int signo)
{
sigflag = 1;
return;
}
void TELL_WAIT()
{
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("signal SIGUSR1 error\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("signal SIGUSR2 error\n");
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)
printf("SIG_BLOCK error\n");
}
void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we are done */
}
void WAIT_PARENT()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1);
}
void WAIT_CHILD()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void do_task(char *task_str)
{
printf("%s\n", task_str);
}
/* parent goes first program */
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
WAIT_PARENT();
do_task("child task\n");
}
else {
do_task("parent task\n");
TELL_CHILD(pid);
}
return 0;
}
/* child goes first program*/
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
do_task("child task\n");
TELL_PARENT(getppid());
}
else {
WAIT_CHILD();
do_task("parent task\n");
}
return 0;
}
/*
* 使用管道实现父子进程同步
*
* 父进程在调用TELL_CHILD 时经由上一个管道写一个字符p,子进程在
* 调用TELL_PARENT时,经由下一个管道写一个字符c。相应的WAIT_XXX
* 函数调用read读一个字符,没有读到字符时阻塞(睡眠等待)。
*
*/
static int pfd1[2], pfd[2];
void TELL_WAIT()
{
if(pipe(pfd1) < 0 || pipe(pfd2) < 0)
printf("pipe error\n");
}
void TELL_PARENT(pid_t pid)
{
if(write(pfd2[1], "c", 1) != 1)
printf("write error\n");
}
void WAIT_PARENT()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'p')
printf("WAIT_PARENT: incorrect data\n");
}
void TELL_CHILD(pid_t pid)
{
if(write(pfd1[1], "p", 1) != 1)
printf("write error\n");
}
void WAIT_CHILD()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'c')
printf("WAIT_CHILD: incorrect data\n");
}
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询