您的位置:首页 > 其它

使用信号signal,实现进程之间的同步

2010-08-12 15:14 555 查看
下面是具体的代码,其中四个函数是重点。

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐