linux键盘信号程序,linux中的 【信号】

信号的产生方式:

1、键盘输入

如 Ctrl+C 表示产生一个SIGINT信号

2、异常产生信号

如 程序执行到 2/0 这种情况、 管道的读段已经关闭而写端仍向管道中写入数据这种情况 等...

3、通过命令向指定进程发送信号

对信号的处理方式:

1、忽略

2、执行默认处理(通常为终止程序)

3、执行自定义动作 (信号的捕捉)

举个例子。

下面这段程序,从0开始,每隔一秒输出一个不断增长的数值

8c22e03c47f3ac3a3f2a6f9130d5b686.png

执行:

4ee03ffff1ce72fe54efdd8311e66d04.png

显然 它是一个死循环,将会一直执行下去

用信号中断它,可以直接用Ctrl + C

这样内核会对该进程发送一个 SIGINT 信号,结束当前进程:

2ce9fbfa7044f9aff18852f608ea9e46.png

此外,执行程序后 另外打开一个终端

(其实在执行命令的语句后面加上 & 就可以让当前进程在后台运行,也就不需要另外打开中断了,这里这样做是为了更直观一些)

先用 ps aux 命令查找到当前进程的 PID

然后用 killl -l 命令查看所有信号:

cbac1764576fa51a901a14f01d859eff.png

这里能够发现, Ctrl+C快捷键发送的 SIGINT 信号对应的2,

而我当前进程的PID 为:20262

那么,执行命令  : kill -2 20262 或者 kill -SIGINT 20262

发现死循环的进程终止了

接下来介绍几个信号集操作函数:int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set, int signo);

int sigdelset(sigset_t *set, int signo);

int sigismember(const sigset_t *set, int signo);

int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

int sigpending(sigset_t *set);

第一个函数:

sigemptyset 用来初始化 set 指向的 信号集,使所有信号对应的bit清零,表示该信号集不包含任何有效信号

成功返回0,出错返回 -1

第二个函数:

sigfillset 同样用来初始化,不过跟上面那个 sigemptyset 作用相反,它表示该信号集包括系统支持的所有信号

成功返回0,出错返回 -1

在使用 sigset_t 类型变量之前,必须调用上述两个初始化阐述中的任意一个

第三个函数:

sigaddset 的作用是向指定信号集 set 中添加 有效信号

成功返回0,出错返回 -1

第四个函数:

sigdelset 的作用是在指定信号集 set 中 删除有效信号

成功返回0,出错返回 -1

第五个函数:

sigismember 用来判断指定的信号是否在指定信号集中

若存在,返回1;  若不存在,返回0;  若出错,返回-1

第六个函数:

sigprocmask 可以读取或更改进程的信号屏蔽字int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

成功返回0,失败返回-1

其中第一个参数 how表示处理方式,有以下三种:

·SIG_BLOCK :

set包含了我们希望添加到当前信号屏蔽字的信号  //相当于mask = mask | set

·SIG_UNBLOCK :

set包含了我们希望从当前信号屏蔽字中解除阻塞的信号  //相当于 mask = mask | ~set

·SIG_SETMASK :

设置当前信号屏蔽字为set所指向的值    //相当于 mask = set

第七个函数:

sigpending 读取当前进程的未决信号集,通过set参数传出

成功返回0,失败返回-1

接下来,用上面介绍的7个函数,实现一段功能

7d7022639b07121ae97f82b0c2056244.png

这里我定义的 print_sig 函数的作用是 将指定信号集的所有信号的存在情况打印出来

main函数中, 第35行 将SIGINT信号添加进 s 信号集当中

然后37行的 sigprocmask 执行完毕后,  SIGINT信号就相当于被阻塞了,同时,o保存的信号集就是之前的s(全 0)

while循环 每次读取并打印 当前的未决信号集  每循环5次就恢复一次阻塞,如果没有信号被阻塞,则打印“recover block” 并继续执行循环,

如果有信号被阻塞,那么在49行恢复阻塞完毕后,程序就会终止掉。

运行结果:

b64a96e27a443b24c5215d9b5cc7da8a.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值