内核中几个用于信号产生的函数:
specific_send_sig_info():向进程发送信号
group_send_sig_info():向进程组发送信号
send_signal(): 将信号插入挂起信号队列
specific_send_sig_info()
向t发送信号sig
参数
- sig
信号ID
- info
信号的附加信息
- t
进程描述符
其中,参数info
可能的取值如下:
值 | 意义 |
---|---|
(siginfo_t) | info是指向siginfo_t结构的指针 |
0 | 信号由用户发送 |
1 | 信号由内核发送 |
2 | 信号由内核发送,且信号是:SIGSTOP或SIGKILL |
复杂性
t阻塞这个信号
t被跟踪
sig是实时信号
sig已经挂起在t的pending列表上
sig必须插入到t的pending列表上,并且这个过程可能失败
内核需要通知t有新的挂起信号
TIF_SIGPENDING需要被置位
进程状态是TASK_INTERRUPTIBLE或TASK_STOPPED的时候,需要唤醒进程
t正在另一个处理器上运行
send_signal()
向指定进程的挂起队列中插入新元素
参数
- sig
信号ID
- info
附加信息
- t
进程描述符
- signals
挂起信号队列的地址
复杂性
sig是实时信号;
sig是SIGKILL或SIGSTOP,这两个信号不能被阻塞,忽略和捕捉(APUE);
t->user->sigpending大于t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur;
分配新的sigqueue结构失败;
为用户簿记资源;
设置队列位掩码中与信号相关的位
;
将sig插入到t的挂起信号队列以后,顺手阻塞sig,这是普通信号的特征,我可以理解.但是,sigaddset(&signals->signal, sig);
这行代码疑点太多:
1.signals是什么类型的数据结构?为什么signals->signal会指示一个sigset_t域?signals->signal是挂起信号队列的阻塞信号掩码,如pending.signal和shared_pending.signal;而进程描述符的blocked是做什么用的呢?我知道用处之一是作为do_signal()的oldset参数的替补.
2.为什么这行代码要在第7步和第10步执行两次?
group_send_sig_info()
向p所在的线程组发送信号sig
参数
- sig
- info
- p
进程描述符的地址
复杂性
sig是一个错误的值
这个函数可由用户进程调用或接受来自用户进程的参数用户进程越权发出此信号
sig=0
目标进程可能正被杀死
为什么正在被杀死的进程要做特殊处理?sig可能使p线程组中的其他挂起信号无效
之前的函数为什么不检查这一点?p忽略sig
sig已有一个挂起的实例
向共享挂起信号队列中添加sig
从p中唤醒一个进程处理sig