面试中关于Linux的信号常问的问题

来源:互联网 发布:sqlserver 临时表 编辑:程序博客网 时间:2024/05/18 02:44

简介

信号:进程间用于通知进程有某种事件发生,也可以发信号给进程本身,它是一种异步事件。但是要注意的是,除了内核和root,只有具备相同id的进程才可以用信号通信。

信号的整个生命周期

先由外界产生信号,信号进入内核,内核就会把信号记录到目标 进程的进程描述符中。再在一个合适的时机递送到进程中,合适的时机指的就是有时候 进程正在执行比较重要的代码,这个时候信号就会被阻塞直到阻塞解除。

信号的产生

来自硬件异常:比如访问了非法的内存地址,或者除了0。
来自终端输入:比如用户在终端上输入了ctrl+C就会产生SIGINT信号,在system V标 准下signal注册的信号是ONESHOT的,也就是说信号被触发一次之后,要重置信号处 理函数,否则会是用默认的处理函数。
软件相关信号:比如子进程退出内核就会向父进程发送SIGCHLD信号。

SystemV中信号是可重入的,也就是说在处理A信号的时候可以再次接受A信号,这是 SystemV的一个弊端。在BSD的风格中,处理A信号时会屏蔽A信号,但是并不会屏蔽 其他信号。这正是因为SystemV在调用rt_sigaction)时也就是信号处理函数时加上了 SA_NODEFER标志位,也就是信号处理函数执行不推延。

如果在一个进程执行系统调用(例如read,write)的时候,收到一个信号,此时系统 调用会中断,接着进入信号处理,处理完进程后会再次重启系统调用。

信号的可靠性

信号分为可靠信号和不可靠信号,不可靠信号就是指发送的信号内核不一定能够发送给 目标进程,信号可能丢失。
不可靠信号在内核中存储的方式是位图和链表,当内核接收一个信号后,先判断它是否 已经存在,不存在就把他对应的位置一,并将信号挂入链表,存在则丢弃信号。
可靠信号则是把信号放入队列,再链入链表,所以也就保证了信号不丢失。

信号的递送顺序

如果存在多个未决信号,同一个未决信号会按照发送顺序来递送信号,不同的未决信 号按照信号的序号大小来递送,序号小的信号会先被递送到进程。另外,linux中会优 先递送不可靠信号

多线程中信号造成死锁

如果一个线程持有锁,在操作临界区内容时,被信号中断了,转而去执行信号处理函数, 而信号处理函数再次对临界区加锁就会造成死锁。
解决的方法就是使用信号等待函数,线程阻塞等待信号处理函数直到处理完毕,也就是 所说的化异步为同步。

原创粉丝点击