Linux系统应用编程---信号

简介: Linux系统应用编程---信号

一、信号产生种类

1、特殊终端按键

Ctrl+C                  SIGINT

Crtl+Z                  SIGTSTP

Ctrl+\                   SIGQUIT

2、硬件异常

除0操作

访问非法内存

3、Kill函数或者kill指令

#include <sys/types.h>

#include <signal.h>

int kill(pid_t pid, int sig);

pid参数说明

Pid参数

说明

Pid > 0

Sig发送给ID为pid的进程

Pid = 0

Sig信号发送给与调用kill的那个进程同组的所有进程

Pid = -1

sig信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。

Pid < -1

sig发送给组ID为|-pid|的进程,并且发送进程具有向其发送信号的权限

sig参数为kill –l看到的前32个信号

4、某种软件条件已经发生

比喻定时器定时1s

1. #include <stdio.h>
2. #include <unistd.h>
3. 
4. 
5. int main(void)
6. {
7.        int counter;
8.        alarm(1);
9. /*
10. 
11.               sleep(1)与alarm(1)的区别
12.               sleep(1)就是睡在这里,下面的代码不去执行
13.               alarm(1)只是定时1s,下面的代码还是会继续执行
14. */
15. 
16. for(counter=0; 1; counter++)
17.               printf("counter = %d.\n", counter);
18. 
19. return 0;
20. }

 

二、进程处理信号行为

manpage里信号有3种处理方式

1.默认处理动作(man 7 signal可以看到)

term                     终止此信号

core                     终止当前进程并且产生段错误

ign                       忽略此信号

stop                     暂停(挂起)此信号

cont                     继续此进程的执行(暂停之后继续)

2.忽略

3.捕捉(用户自定义信号处理函数,类似于中断服务程序)

三、信号处理函数

实际执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending)。进程可以选择阻塞(Block)某个信号。被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

 

下图给出信号从产生到抵达的执行过程

1、阻塞信号集是用户可以设置的,未决信号集是用户不能设置的;

2、系统规定有2个信号不能被阻塞,SIGKILL和SIGSTOP

3、内核向进程发送一个信号,到信号的执行过程分为以下步骤

(1)首先未决信号集对应的信号位会置1,

(2)去判断阻塞信号集对应的信号位是否为1,若为1则阻塞,若为0则信号递达,并执行handle

(3)当执行完之后,未决信号集对应的信号位被翻转成0

4、未决和阻塞标志都可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可表示每个信号的“有效”或“无效”状态。阻塞信号集中“有效”和“无效”分别表示该信号是否被阻塞;未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。

5、阻塞信号集也叫当前进程的信号屏蔽字(Signal mask),这里的屏蔽应该理解为阻塞而不是忽略。

信号集处理函数

sigaction函数

四、C标准库提供的信号处理函数

signal函数和system函数

1. typedef void (*sighandler_t)(int)
2. 
3. sighandler_t signal(int signum, sighandler_t handler)

程序:

1. #include <stdio.h>
2. #include <signal.h>
3. #include <unistd.h>
4. 
5. 
6. void do_sig(int n)
7. {
8. printf("hello.\n");
9. }
10. 
11. int main(void)
12. {
13. signal(SIGINT,do_sig);
14. 
15. while(1){
16. printf("*******************\n");
17. sleep(1);
18.        }
19. 
20. return 0;
21. }

执行结果如下:

按下Ctrl+C 发送SIGINT信号,执行do_sig函数,打印hello

目录
打赏
0
0
0
0
20
分享
相关文章
Linux系统中的cd命令:目录切换技巧
踏过千山,越过万水,人生就是一场不断前行的旅程,总充满了未知与挑战。然而,“cd”命令如同你的旅伴,会带你穿梭在如棋盘一般的文件系统中,探索每一处未知。希望你能从“cd”命令中找到乐趣,像是掌控了一种络新妙的魔法,去向未知进发,开始你的探索之旅。
94 24
|
9天前
|
Linux系统下快速批量创建和删除文件的方法
总的来说,使用shell脚本来批量处理文件是一种非常强大的工具,只要你愿意花时间学习和实践,你会发现它能大大提高你的工作效率。
64 19
Linux系统之su命令的基本使用
Linux系统之su命令的基本使用
68 2
Linux系统之su命令的基本使用
在Ubuntu Linux系统下如何搭建并安装EDK2
以上就是在Ubuntu Linux系统下搭建并安装EDK2的过程。这个过程可能会有些复杂,但只要按照步骤一步步来,应该不会有太大问题。如果在过程中遇到任何问题,都可以在网上找到相应的解决方案。希望这个指南能对你有所帮助!
71 17
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
121 27
|
11月前
|
Linux下的系统编程——守护进程、线程(十二)
Linux下的系统编程——守护进程、线程(十二)
106 0
Linux下的系统编程——守护进程、线程(十二)
Linux系统编程(守护进程)
Linux系统编程(守护进程)
101 0
Linux系统编程---守护进程
守护进程是什么?就是在后台运行的进程。 那么如何创建守护进程呢?  1. 创建孤儿进程 2. setsid() 创建进程会话 3. 重定向标准输入, 标准输出 4. chdir, 改当当前进程的工作目录 接下来看一个例子: #include #include #include int ...
922 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等