Linux练习题,父子进程通过信号通信,实现交替数数。
父子进程交替发信号进行驱动从而实现数数,值得注意的是 不管是父进程或者子进程谁先发送信号 都会面临一个问题,另外一个进程的信号捕捉函数是否已经注册了!所以有2种方式,一种是 最先发送信号的进程先 sleep一下等另外一个进程的信号捕捉函数注册完毕了 就可以发送信号进行相互驱动。第二种方式,采用阻塞信号集的方式,在后数数的进程注册信号捕捉函数前 将其信号进行阻塞,待其信号捕捉函数注册完毕 然后再解除阻塞。
#include
#include
#include
#include
#include
#include
#include
#include
#include
void perr(const char* str)
{
perror(str);
exit(1);
}
int num = 0;
int num1 = 1;
pid_t son_pid;
void father_num(int signo)
{
printf("father\tnum = %d\n",num1);
num1+=2;
sleep(1);
kill(son_pid,SIGUSR2);
}
void son_num(int signo)
{
printf("son\tnum = %d\n",num);
num+=2;
sleep(1);
kill(getppid(),SIGUSR1);
}
//父子进程通过信号通信,实现交替数数
//使用用户定义的信号,在父子进程间进行信号通信
//儿子先数数
int main(int argc,char* argv[])
{
pid_t pid;
int ret;
struct sigaction act1,act2;
sigset_t set;
//设置信号阻塞一定是在fork前,这样才能保证,发送给子进程的SIGUSR2信号被阻塞
sigemptyset(&set);
sigaddset(&set,SIGUSR2);
sigprocmask(SIG_BLOCK,&set,NULL);
pid = fork();
son_pid = pid ;
if(pid > 0)
{
//让儿子将信号捕捉函数先注册,再才给子进程发信号
//可以先让父亲睡一会,或者将发送给子进程的信号阻塞 等待子进程注册完毕再解除阻塞
//这样的话,父进程和子进程相互发的信号就不能一样,不然会搞混
//sleep(1);
//父进程
act1.sa_flags = 0;
sigemptyset(&act1.sa_mask);
act1.sa_handler = father_num;
//注册捕捉信号函数
sigaction(SIGUSR1,&act1,NULL);
kill(pid,SIGUSR2);
while(1);
}else if ( pid == 0 )
{
//子进程
act2.sa_flags = 0;
sigemptyset(&act2.sa_mask);
act2.sa_handler = son_num;
//注册捕捉信号函数
ret = sigaction(SIGUSR2,&act2,NULL);
//子进程注册完信号捕捉函数 就可以解除对子进程的信号阻塞了
sigprocmask(SIG_UNBLOCK,&set,NULL);
if(ret < 0)
{
perr("sigaction error");
}
while(1);
}else
{
//error
perr("fork error");
}
return 0;
}