实现:父子进程实现交替报数
父进程给子进程发送限号SIGUSR2
子进程给父进程发送信号SIGUSR1
由于父子进程通信,因此需要定义父进程和子进程各自的捕捉函数
//信号实现父子进程间通信
/*Parent send SIGUSR2*/
/*Child Send SIGUSR1*/
/*SIGUSR1,SIGUSR2 默认状态为杀死进程*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
//父进程捕捉函数
void sig_Parent(int n,siginfo_t *Info,void *arg)
{
sleep(1);
//输出数据
printf("parent process pid %d receive data %d\n",getpid(),Info->si_int);
union sigval sgv;
sgv.sival_int = ++(Info->si_int);
//向子进程发送信号和数据
sigqueue(getpid()+1,SIGUSR2,sgv);
}
//子进程捕捉函数
void sig_Child(int n,siginfo_t *Info,void *arg)
{
sleep(1);
//输出数据
printf("child process pid %d receive data %d\n",getpid(),Info->si_int);
union sigval sgv;
sgv.sival_int = ++(Info->si_int);
//向子进程发送信号和数据
sigqueue(getpid()-1,SIGUSR1,sgv);
}
int main(void)
{
//将子进程接受的信号屏蔽
sigset_t set,oset;
sigemptyset(&set);
sigaddset(&set,SIGUSR2);
sigprocmask(SIG_SETMASK,&set,&oset);
//创建父子进程
pid_t pid;
pid = fork();
if(pid > 0)//父进程
{
//捕捉结构体
struct sigaction nact,oact;
nact.sa_sigaction = sig_Parent;
nact.sa_flags = SA_SIGINFO;
sigemptyset(&nact.sa_mask);
sigaction(SIGUSR1,&nact,&oact);
//定义联合体
union sigval sgv;
sgv.sival_int = 1;
//向子进程发送消息
sigqueue(pid,SIGUSR2,sgv);
while(1)
sleep(1);
}
else if(pid == 0)//子进程
{
//捕捉结构体
struct sigaction nact,oact;
nact.sa_sigaction = sig_Child;
nact.sa_flags = SA_SIGINFO;
sigemptyset(&nact.sa_mask);
sigaction(SIGUSR2,&nact,&oact);
//解除屏蔽
sigdelset(&set,SIGUSR2);
sigprocmask(SIG_SETMASK,&set,&oset);
while(1)
sleep(1);
}
else
{
perror("call fork error");
exit(0);
}
return 0;
}
我们可能会有疑问,为什么要屏蔽子进程信号?·
这是因为,当父进程创建子进程时,由于开始时子进程的信号捕捉还没有发生,
当内核收到父进程发送的消息时,状态为杀死子进程, 为了解决这个问题,
在子进程一出生就是屏蔽的,子进程捕捉完成后解除屏蔽