下面是具体的代码,其中四个函数是重点。
TELL_WAIT, WAIT_PARTEN, TELL_PARTEN, WAIT_CHILD, TELL_CHILD。
TELL_WAIT是用来初始化信号掩码的。至于为什么要block SIGUSR1 和 SIGUSR2我还不清楚。
其余四个就是两对,用来等待和告知。
关键的是两个
1.用了一个static volatile sig_atomic_t sigflag 变量来做flag。
2. 用sigsuspend来等待信号的到来。
在调试的过程中发现,因为文件写的时候会有延时,所以要每次写完后fclose该文件。
/*
* =====================================================================================
*
* Filename: parent_child.c
*
* Description:
*
* Version: 1.0
* Created: 08/12/2010 10:47:11 AM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Company:
*
* =====================================================================================
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.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)
perror("signal(SIGUSR1) error");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
perror("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)
perror("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)
perror("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)
perror("SIG_SETMASK error");
}
int main()
{
FILE * pFile;
char buffer[10] = {0};
pid_t pid;
int i;
int d;
pFile = fopen("interaction","wb+");
fwrite("2", 1, 1, pFile);
fclose(pFile);
TELL_WAIT();
pid = fork();
if (pid < 0)
{
perror("fork error");
return 0;
}
else if(pid == 0)
{
for (i=0;i<10;i++)
{
pFile = fopen("interaction","rb+");
fread(buffer, 1, sizeof(buffer), pFile);
printf("chile get: %s/n", buffer);
sscanf(buffer, "%d", &d);
rewind(pFile);
sprintf(buffer, "%d", d+1);
fwrite(buffer, 1, sizeof(buffer), pFile);
fclose(pFile);
printf("child put: %s/n", buffer);
TELL_PARENT(getppid());
WAIT_PARENT();
}
}
else if (pid > 0)
{
for (i=0;i<10;i++)
{
WAIT_CHILD();
pFile = fopen("interaction","rb+");
fread(buffer, 1, sizeof(buffer), pFile);
printf("father get: %s/n", buffer);
sscanf(buffer, "%d", &d);
rewind(pFile);
sprintf(buffer, "%d", d+1);
fwrite(buffer, 1, sizeof(buffer), pFile);
fclose(pFile);
printf("father put: %s/n", buffer);
TELL_CHILD(pid);
}
}
return 0;
}