zoukankan      html  css  js  c++  java
  • 一起talk C栗子吧(第八十五回:C语言实例--使用信号进行进程间通信二)


    各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的样例,这一回咱们接着上一回的内容,继续说该样例。闲话休提。言归正转。

    让我们一起talk C栗子吧。

    我们在上一回中举了使用信号进行进程间通信的样例,在该样例中。我们通过终端发出信号。当进程收到该信号后让它运行系统对信号定义的默认动作。这一回。我们再来举一个使用信号进行进程间通信的样例,只是。我们发送和处理信号的方式和上一回的样例不一样。在接下来的样例中,我们在一个进程中使用kill产生信号。在另外一个进程中接收而且依照自己的方式处理接收到的信号

    在样例中我们使用kill函数给其他进程发送信号,以下是kill函数的原型

    int kill(pid_t pid, int signo);
    • 第一个參数pid表示进程的PID。kill函数将把信号发送给PID与其參数同样的进程;
    • 第二个參数表示信号。该參数表示kill函数发送的信号值。

    • 假设kill成功发送信号,那么返回0,否则返回-1.

    在样例中我们使用signal函数设置接收到信号后的处理方式。以下是signal函数的原型

    void (*signal(int signo, void (*func) (int))) (int)

    大家看着这个函数是不是认为有点乱?先别慌。我们慢慢对它进行分析。

    这个函数名叫signal,它用来配置信号处理函数,通俗点说,它就是为某个信号分配一个信号处理函数。

    它有两个參数:

    • 一个參数是signo,表示信号值。
    • 另外一个參数是一个名叫func的函数指针,它表示信号处理函数。
    • 也就是说进程接收到signo表示的信号后会使用该函数来处理信号。

    • 參数中的func是一个函数指针,它指向的函数包括一个int类型的參数,表示信号值,该函数返回void。
    • 最后,我们说一下signal函数的返回值,它返回一个函数。该函数就是func指向的信号处理函数。

    接下来,我们通过具体的代码来说明它们的使用方法

    #include<unistd.h>
    #include<signal.h>
    #include<stdio.h>
    
    void sig_receive(int signo)
    {
        printf("received signal :%d 
    ",signo);
    }
    
    int main()
    {
        pid_t pid;
        int pid_res;
        int stat_value;
    
        pid = fork();
    
        if(pid > 0)
        {
            printf("PID: %d -> Father Process send signal
    ",getpid());
            kill(pid,SIGALRM);   //发送信号
        }
        else if(pid == 0)
        {
            signal(SIGALRM,sig_receive);  //配置信号处理函数
            printf("PID: %d -> Son Process receive signal 
    ",getpid());
        }
        else
        {
            printf("Create process failed 
    ");
            return 1;
        }
    
        pid_res = wait(&stat_value);
    
        if(pid_res > 0)
        {
            printf("Son process finished: PID = %d 
    ",pid_res);
        }
    
        return 0;
    }

    从上面的代码中能够看到,我们在父进程中使用kill函数发送信号,然后在子进程中使用signal函数配置信号处理函数,当子进程收到信号后。信号处理函数就会对该信号进行处理。

    看官们,正文中就不写代码了,具体的代码放到了我的资源中,大家能够点击这里下载使用。

    以下是程序的运行结果,请大家參考

    PID: 3208 -> Father Process send signal      //父进程发送信号
    received signal :14                          //信号处理函数在处理信号
    PID: 3209 -> Son Process receive signal      //子进程收到信号
    Son process finished: PID = 3209             //子进程结束,父进程也结束    

    看官们,从程序的结果中能够看出,父进程发出信号后,子进程收到了信号,而且进行了处理

    这说明我们通过信号在两个进程之间进行了通信

    看官们,有个小的细节不知道大家有没有发现:程序运行结果中先是运行信号处理函数中的内容,然后才运行子进程中的内容。假设我们把运行的顺序调换一下会有什么现象呢?

    把以下这两行代码的运行顺序调换一下,也是说把printf语句放在signal配置语句的前面。

            signal(SIGALRM,sig_receive);  //配置信号处理函数
            printf("PID: %d -> Son Process receive signal 
    ",getpid());

    又一次编译而且运行程序后,得到以下运行结果

    PID: 2611 -> Father Process send signal  //父进程发送信号
    Son process finished: PID = 2612         //子进程结束,父进程也结束     

    从上面的结果中以能够看到,子进程不但没有收到信号。而且没有运行。这是什么原因呢?那是由于父进程发信号的时候子进程可能被堵塞,所以没有运行。这也是signal函数缺点。

    signal函数是早期Unix系统提供的函数,如今的新系统中已经使用sigaction函数代替它。只是在一些老的程序中还是能看到它的身影。下一回中。我们将介绍sigcation函数相关的内容。

    各位看官,关于使用信号进行进程间通信的样例咱们就讲到这里。

    欲知后面还有什么样例,且听下回分解 。


  • 相关阅读:
    antd vue 刷新保留当前页面路由,保留选中菜单,保留menu选中
    你不知道的arguments
    js触发复制、粘贴,设置和读取剪切板的数据
    vue父组件data改变触发子组件prop值变化
    关于英语的unless
    PHP闭包调用外部参数使用范例
    全国省市区数据库数据,以及可视化echarts相关geoJson数据
    PHP开发环境搭建&mdash;phpstudy+eclipse+php development tool+xdebug+composer
    LBS——实现附近功能的几种方案浅谈
    好文共赏
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7360406.html
Copyright © 2011-2022 走看看