博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 信号机制
阅读量:4121 次
发布时间:2019-05-25

本文共 1206 字,大约阅读时间需要 4 分钟。

本文旨在弄懂linux中的信号工作原理

1 查看所有信号

kill -l 命令可以查看linux下所有信号

2 信号产生

2.1 用户在终端按下某些键时,终端驱动程序会发送信号给前台进程

例如Ctrl-C产生SIGINT信号,Ctrl-\产生SIGQUIT信号,Ctrl-Z产生SIGTSTP信号

2.2 硬件异常产生信号,这些条件由硬件检测到并通知内核,然后内核向当前进程发送适当的信号

例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程

2.3 一个进程调用kill(2)函数可以发送信号给另一个进程

2.4 可以用kill(1)命令发送信号给某个进程,kill(1)命令也是调用kill(2)函数实现的,如果不明确指定信号则发送SIGTERM信号,该信号的默认处理动作是终止进程

2.5 当内核检测到某种软件条件发生时也可以通过信号通知进程,例如闹钟超时产生SIGALRM信号,向读端已关闭的管道写数据时产生SIGPIPE信号

关于调用函数向进程发送信号

#include 
int kill(pid_t pid, int signo);int raise(int signo);

上面的两个函数,我们来解释一下, 

kill函数两个参数,pid为给哪个进程要发信号,signo为哪中信号。 
raise函数其实是kill函数的封装,raise函数是自己给自己发送任意信号。 
上面两个函数都是成功返回1,失败返回0

3 信号的阻塞

信号产生时,内核在该进程控制块PCB中设置该信号的未决标志,直到信号递达才清除该标志。 信号在内核中的示意图 

è¿éåå¾çæè¿°

信号递达(Delivery):实际执行信号的处理动作

信号未决(pending):信号从产生到递达之间的状态

信号阻塞(block):产生信号,信号也不会被递达。被阻塞的信号产生时将保持在未决状态,信号被阻塞了就不被递达。 

未决和阻塞标志可以用相同的数据类型sigset_t存储,sigset_t称为信号集

进程可以选择阻塞某个信号 如果在信号未决后,我们设置了阻塞,那么该信号会在未决表中等待解除阻塞 在信号中我们要明白,信号的阻塞和忽略不同,忽略是信号的处理方式,而阻塞只是信号在传递过程中,对信号的一种延后处理的行为。

信号未阻塞也未产生,当它递达时执行默认处理动作

信号产生但被阻塞,所以暂时不能递达。尽管处理动作是忽略,但是在解除阻塞之前还不能忽略该信号,因为进程仍有机会改变对信号的处理动作之后再解除阻塞

4 信号处理

忽略:忽略此信号。

默认:执行该信号的默认处理动作 自定义捕捉。

捕捉:提供一个信号处理函数,要求内核在处理信号时切换到用户态执行这个处理函数。

 

 

 

参考

 

你可能感兴趣的文章
一篇搞懂Java反射机制
查看>>
【2021-MOOC-浙江大学-陈越、何钦铭-数据结构】树
查看>>
MySQL主从复制不一致的原因以及解决方法
查看>>
RedisTemplate的key默认序列化器问题
查看>>
序列化与自定义序列化
查看>>
ThreadLocal
查看>>
从Executor接口设计看设计模式之最少知识法则
查看>>
OKhttp之Call接口
查看>>
application/x-www-form-urlencoded、multipart/form-data、text/plain
查看>>
关于Content-Length
查看>>
WebRequest post读取源码
查看>>
使用TcpClient可避免HttpWebRequest的常见错误
查看>>
EntityFramework 学习之一 —— 模型概述与环境搭建 .
查看>>
C# 发HTTP请求
查看>>
启动 LocalDB 和连接到 LocalDB
查看>>
Palindrome Number --回文整数
查看>>
Reverse Integer--反转整数
查看>>
Container With Most Water --装最多水的容器(重)
查看>>
Longest Common Prefix -最长公共前缀
查看>>
Letter Combinations of a Phone Number
查看>>