Linux系统编程:习题,父子进程通过信号通信,实现交替数数

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;
}

运行效果

Linux系统编程:习题,父子进程通过信号通信,实现交替数数_第1张图片

你可能感兴趣的:(【Language_C】)