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

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

这里我指定用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;
}

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

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

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值