使用信号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;
}
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;
}
相关文章推荐
- 信号实现父子进程之间的同步--sigsuspend的作用
- 信号实现父子进程之间的同步--sigsuspend的作用
- 信号实现父子进程之间的同步--sigsuspend的作用
- 信号实现父子进程之间的同步--sigsuspend的作用
- 可以用信号实现父、子进程之间的同步
- 信号实现父子进程之间的同步--sigsuspend的作用
- 使用共享实现两个进程之间的聊天-使用有名信号量实现同步
- 多线程 : 使用 wait 和 notify 实现进程间同步通信
- SQL Server - 使用 Merge 语句实现表数据之间的对比同步
- c# 进程间同步实现 进程之间通讯的几种方法
- [Linux信号]进程间使用信号进行同步
- c# 进程间同步实现 进程之间通讯的几种方法
- 使用临界段实现优化的进程间同步对象-原理和实现 (转)
- NTP协议以及ntpclinet使用 From Evernote: NTP协议以及ntpclinet使用 NTP全称是Network Time Protocol,是用来让计算机之间实现时间同步的协议
- SQL Server - 使用 Merge 语句实现表数据之间的对比同步
- 共享内存多进程间通信,进程间同步使用信号量来实现
- 使用SharedPreferences实现Activity和Service之间数据同步问题
- C#使用互斥量(Mutex)实现多进程并发操作时多进程间线程同步操作(进程同步)的简单示例代码及使用方法
- Linux下通过共享内存进行进程间通信,进程间同步使用信号量来实现
- 使用databus实现oracle和内存数据库redis之间的数据同步