当前位置:   article > 正文

操作系统笔记(4):通过信号signal进行进程间通信——kill()系统调用实现的软中断_kill signal

kill signal

kill的理解

看到这里的同学应该至少知道,在LinuxShell里面,
kill命令可以指定一个进程PID然后杀掉吧

如图 先用ps -all获取所有可见进程列表,找到想要杀掉的进程PID(这里是一个叫做m的进程)
kill命令即可杀掉。
在这里插入图片描述在这里插入图片描述
但事实上,这里的kill尽管是在命令行里面敲出来的,其本质还就是一种进程间通信

从你的命令行(普通用户的)bash进程发送给指定PID的进程,然后触发接收进程的软中断,进程就暂停手下的工作,去执行默认的信息接收处理程序。

然后直接输入kill默认带有参数为-15,宏变量为SIGTERM也就是Terminate的意思,表示终止

接收到这个参数的进程触发软中断,暂停自己在做的事情,去执行由参数15引发的软中断处理程序——终止!

还有很多参数可以用kill发送出去,而且很多都是在软中断中实现终止、中断、退出的!比如比15更强的kill -9我想这就是为什么发送的系统调用函数叫做kill而不是send一类的吧)
所有参数与其宏变量现实如下,用kill -l可以列出来
在这里插入图片描述
此外拓展一下,使用Ctrl+C,或者是Ctrl+\去强制停止某个进程,也就分别等于写了kill -2kill -3进行进程的中断和退出哦!

代码实现

所以说,只要你在用kill去杀进程,你就是在实际地利用软中断机制进行进程间通信!
那么现在我们就要把这个机制运用到具体的C语言程序中吧。
首先我们要学一个系统调用函数signal()
它的作用简单的来说,就是告诉系统,我这个进程如果收到一个指定的信号,就触发我的软中断去运行指定的方法
代码如下:

#include<stdio.h>
#include<signal.h>
void sayHello(){
    printf("\nHello!\n");
}

int main(){
    signal(2,sayHello);
    while(1);
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里我指定用2这个信号值,因为直接使用Ctrl+C就相当于发送kill -2。这样就不需要再开一个终端命令行,ps找到进程,再用kill发送信息,更方便
运行结果演示如下:
在这里插入图片描述
代码解释如下:
这里我们在代码中用signal系统调用,将sayHello这个方法覆盖掉原本进程响应kill -2的中断方法。它就在收到2这个信号后触发软中断转而执行sayHello。

最后别担心停不下来,kill里面很多命令都可以退出进程Ctrl+\即可。

接下来我们构造两个进程,互相之间通过kill发送命令

测试代码如下:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<sys/time.h>

void msleep(int ms){
    struct timeval tval;
    tval.tv_sec=ms/1000;
    tval.tv_usec=(ms*1000)%1000000;
    select(0,NULL,NULL,NULL,&tval);
}

void fatherGet2(){
    printf("\nIm father and i just get 2\n");
}
void sonGet2(){
    printf("\nIm son and i just get 2\n");
}
int main(){
   
    pid_t pid = fork();
    if(pid){
        //father process
        signal(2, fatherGet2);
        while (1){
            msleep(2000);
            kill(pid, 2);
        }
    }else{
        //son process
        signal(2, sonGet2);
        while(1){
            msleep(1000);
            kill(getppid(), 2);
        }
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

实现功能为父子进程互相发送信息2:
其中父进程每2秒发送一次,子进程每1秒发送一次。
运行:
在这里插入图片描述
发现确实成功进行通信了,但是好像比例不对嘛,而且打印速度很快显然不是以秒为间隔单位的。
这里是因为我们使用了一句sleep()进行等待,而发生软中断回到原进程时,会由于sleep代码的特殊性导致认为sleep()已经完成了,于是直接继续循环。
这里还是挺要命的,因此在代码中还是尽量不用sleep吧!
当然,本代码解决方案也比较简单,写两句sleep就能减速了呗。。

无论如何,还是成功实现通信了,可喜可贺。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号