您的位置:首页 > 运维架构 > Linux

【Linux】信号的基本概念

2017-06-25 10:18 204 查看

什么是信号

生活中有各类的信号,就拿简单的例子来说吧,上下课的铃声,它可以提示我们哪个时间该上课或者下课。但是当我们收到上课铃声的信号后,到底是去上课,还是去玩,这就是看自己的决定方式了。这就表明我们可以忽略该信号,但是我们是知道该信号的意义的,虽然我们没有遵守,是去玩耍了。或者是墨迹一会再去上课,这就表明生活中的信号是可以不立即处理的。
而计算机中的信号也是类似,进程可以发送信号,也可以接受信号。但一般接受信号后也不会立即进行处理。他们也知道收到对应信号的默认处理动作,也可以选择忽略对应信号,也可以执行自定义的信号。

信号的分类

在Linux下,我们可以通过kill -l来查看所有的信号



其中1-31为普通信号,不支持排队等待,可能会造成信号丢失

34-64为实时信号,支持排队等待,不会造成信号丢失

信号的底层的数据结构是一个位图。

就拿普通信号来说,用32个比特位来表示1-31的信号。全0时表示没有收到信号,当某一位被置为1时,便表示收到了对应的信号

前台进程和后台进程

前台进程:需要和用户进行交互,具有较高的相应速度,优先级别高

后台进程:几乎不和用户进行交互,优先级别相对较低

信号的产生方式

(1)通过终端产生信号

Ctrl+C 产生SIGINT,是普通信号中的2号信号,用来终止信号。

Ctrl+\ 产生SIGQUIT信号,是普通信号中的3号信号,用于捕捉信号。

Ctrl+Z 产生SIGTSTP信号,是普通信号中的20号信号,可以让前台的进程终止。

(2)硬件异常产生信号

当发生除0错误时,CPU的运算单元会产生异常。此刻,内核便将该异常对应的信号SIGFPE发送给进程。

(3)软件条件产生信号

一个进程调用kill(2)信号可以将信号发送给另一个进程;当闹钟超时产生的SIGALAM信号也是软件条件产生信号的一种方式。

#include<stdio.h>
#include<unistd.h>
#include<signal.h>

int main()
{
int count = 1;
alarm(1);
for(; 1; count++)
{
printf("Count = %d\n",count);
}
return 0;
}
运行结果



信号处理方式

(1)忽略 ignore

对应的信号会被清除,进程对齐不产生任何操作

(2)执行默认动作 default

执行对应的信号处理,每个信号都有对应的一种操作

(3)提供信号处理函数,进行自定义 catch

捕获用户的自定义函数,执行用户自定义的函数

signal.c

#include<stdio.h>

void myhandler(int signal)
{
printf("收到了 2 号信号\n");
}

int main()
{
signal(2,myhandler);//对于2号信号,捕获myhandler函数
while(1)
{
sleep(1);
}
return 0;
}


makefile

signal:signal.c
gcc -o signal signal.c
.PHONY:clean
clean:
rm signal


运行结果

信号的捕捉



中断该进程



进程被中断

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: