标签搜索

Linux信号笔记

anker
2021-06-26 / 0 评论 / 8 阅读 / 正在检测是否收录...
  1. 信号是什么
    信号是一种软中断机制实现的进程异步通讯方式。
  2. 信号常见几种产生方式:

    • 用户终端某些按键,比如CTRL+C,CTRL+D,CTRL+Z,CTRL+S,CTRL+Q
    • 硬件异常。除0,无效的内存引用等
    • 用户通过kill、tkill、tgkill、sigqueue、raise函数发送给另一个进程或者进程组或者自己进程一个信号
    • 通过kill命令发送信号
    • 当检测到某种软件条件已经发生,并应将其通知有关进程。如SIGALRM、SIGPIPE(对方已经关闭读,但本端想写)、SIGURG(有带外数据)
  3. 什么是可靠信号,什么是不可靠信号
    由于历史原因,小于32的信号是不可靠信号。反之则为可靠信号。不可靠信号有丢失的可能
  4. 信号生命周期和进程处理信号的时机
    在进程安装信号处理函数后,内核向进程发送信号,其实是向目标进程相关的bitmap结构(信号向量表)中加入记录,此时信号处于pending状态。对于小于32编号的不可靠信号,如果当前已经有这个信号处理pending中,则丢弃。对于可靠信号则进入一个pending队列中。当进程调用系统函数进入内核态返回用户态之前内核进行信号的投递(delivery),转而去执行信号处理函数。这就是一个信号的完整生命周期。如果设定为阻塞,则会一直阻塞。
  5. 程序对信号的响应分类

    • 执行系统默认动作。如果是可靠信号,受到屏蔽字阻塞设定的影响。这些行为一般可以归类为:ignore、terminate、core、stop、continue
    • 设置为忽略此信号。SIGKILL和SIGTOP是不能被忽略的,其他信号都可以忽略。如果是可靠信号,并设置为忽略,则不受到屏蔽字阻塞设定的影响,直接丢弃。不可靠信号没有阻塞的概念。
    • 设置为指定的用户信号处理函数处理。比如捕捉到SIGCHLD信号则表示一个子进程已经终止,可以无阻塞的调用waitpid来取得子进程ID和终止状态。同理SIGKILL和SIGTOP也不能被用户捕捉。如果是可靠信号,受到屏蔽字阻塞设定的影响。
  6. 进程有多线程时,信号是由哪个线程处理的,是什么时机处理的。
    多个线程来说,信号处理函数是共享的。每个线程都拥有独立的阻塞信号掩码。对于多线程的进程,kill和sigqueue发送的信号必须面对所有的线程,而不是某个线程。而系统调用tkill和tgkill发送的信号,又必须递送给进程下某个特定的线程。每个线程都有自己的私有挂起队列(pending),但是进程里的所有线程都会共享一个公有的挂起队列(shared_pending)。如果是发送了指定线程,则进行线程自己队列。那么多线程情况下发送给进程的信号,到底由哪个线程来负责处理?优先查询进程的主线程是否方便处理信号。如果主线程不方便,则会遍历线程组中的其他线程。如果某个线程A设定了对这个信号阻塞、或者正在退出则不由A线程处理。最后的效果就是在这些可以处理的线程中随机一个。
  7. 信号处理函数有什么要注意的,malloc是否可用呢?
    根据上述信号处理函数的执行流程可以看出一位问题是,普通函数可能被中断,而后执行信号函数。这是就有异步安全问题。或者说重入问题。有重入问题的函数都是不用用于信号处理函数中。这和多线程重入的概念相似,但描述的事情不同的。线程安全的函数不一定是异步重入安全的。一般的不可重入函数(man 7 signal):

    • 使用了静态变量,典型的是strtok、localtime等函数
    • 使用了malloc或free函数
    • 标准I/O函数,如printf

    即使是可重入函数,在信号处理函数调用前要先备份errno变量,在离开前恢复errno变量。

  8. 信号为什么会打断系统调用?如何处理?
    系统调用在执行期间,很可能会收到信号,此时进程可能不得不从系统调用中返回,去执行信号处理函数。对于执行时间比较久的系统调用(如wait、read等)被信号中断的可能性会大大增加。系统调用被中断后,一般会返回失败,并置错误码为EINTR。
    Linux操作系统提供了一个标志位SA_RESTART来告诉内核,被信号中断后是否要重启系统调用。如果该标志位为1,则表示如果系统调用被信号中断,那么内核会自动重启系统调用。有些信号即使设置了SA_RESTART也不会自动重启,常见的有epoll_wait, select, 和有超时设置的accept和有超时设置的recv. 这些不能自动重启的函数可以man 7 signal中查看。
0

评论 (0)

取消