1 信号处理程序
1.1 概述
- 信号,软中断信号,用来通知进程发生了某些事件,是一种软件层面上对中断机制的一种模拟。信号本身是一段非常小的信息,一般都只是一个整数。
- 信号的目的有两个:(1)通知进程一个特定的事件发生了;(2)让进程执行一个信号处理函数。
使用kill -l查看系统支持的信号类型如下:
其中,1-31是定期信号,32-64是实时信号。两者的区别在于:内核不支持定期信号的排队,导致,如果某一个定期信号在得到处理前被重复发送了多次,那么只会保留最后一个发送的信号;内核支持实时信号的排队,即重复发送的多个相同的实时信号都会被进程接收并处理。
- 信号的一个重要特征是不可预测性。信号传输包括两个阶段:信号产生和信号发出,信号产生即内核更新进程结构体来表示一个新的信号被发送,信号发出即内核通过改变进程执行状态来强制进程执行一个特定的信号处理函数。每个产生的信号最多被发出一次,信号是一种非常消耗CPU的资源,因为一旦一个信号被发出后,进程描述符的某些信息便会失效,需要更新。
- 信号在产生后、被发出前的这段时间内被称为pending signals(未发信号),一个信号处于未发信号的时间长短是不可预测的。需要考虑的因素如下:(1)信号一般只被发送到当前进程current;(2)一个进程可以阻塞某个信号,那么该种信号便会一直处于阻塞状态,直到进程取消该阻塞;(3)一个进程在执行一个信号处理函数的时候,通常会阻塞其他的信号直到该信号处理程序执行完毕。
- 信号机制中,内核的工作如下:(1)记录哪些信号被进程阻塞;(2)当从内核态切换到用户态的时候,判断进程是否有信号到达;(3)判断哪些信号可以被忽略,主要考虑:目标进程是否被其他进程跟踪、信号是否被阻塞、信号是否默认被忽略;(4)处理信号,保存执行上下文、切换进程状态到信号处理程序、恢复执行执行上下文。
1.2 系统调用
- kill():发送一个信号给线程组;
- tkill():发送一个信号给进程; tgkill():发送信号给一个特定线程组里的进程;
- sigaction():改变信号关联的行为; signal():与sigaction类似;
- sigpending():检查是否有pending signal; sigprocmask():修改阻塞信号的集合;
- sigsuspend():等待一个信号; rt_sigaction():改变一个实时信号关联的行为;
- rt_sigpending():检查是否有pending real-time signal;
- rt_sigprocmask():修改阻塞的实时信号的集合; rt_sigqueueinfo():发送一个实时信号到一个线程组;
- rt_sigsuspend():等待一个实时信号; rt_sigtimewait():与rt_sigsuslend类似;sigwait():如果在线程中调用 sigwait,它会一直等待它指定的信号,直到未决信号集中出现指定的信号为止,同时 sigwait 还会从未决信号集中取出该信号返回,并将该信号从未决非信号集中删除,如果多个线程调用 sigwait 等待同一个信号,只会有一个线程可以从 sigwait 中返回。
- sigfillset():用来将参数set信号集初始化,然后把所有的信号加入到此信号集里即将所有的信号标志位置为1,屏蔽所有的信号。
- pthread_sigmask():设置当前线程的屏蔽信号集合