我的理解如下:
阻塞系统调通通常会将进程置于'TASK_INTERRUPTIBLE'状态,以便在传递信号时,内核将进程置于'TASK_RUNNING'状态。并且该进程将被安排在下一个计时器滴答发生时运行,以便系统调用被中断。
但我做了一个小测试,但失败了。我转发了一个名为sleep()的usermode进程。我在内核中将进程的状态更改为TASK_RUNNING,但是sleep()根本没有被中断,进程仍处于休眠状态。
然后我尝试了wake_up_process(进程),它失败了。
然后我尝试了set_tsk_thread_flag(进程,TIF_SIGPENDING),它失败了。
然后我尝试了set_tsk_thread_flag(进程,TIF_SIGPENDING)和wake_up_process(进程),成功!! sleep()被中断,进程开始运行。
所以不是那么简单。有谁知道系统调用究竟是如何被信号中断的?
答案 0 :(得分:2)
从signal.c
查看__send_signal
。它在结尾附近调用complete_signal
,最终调用这个小函数:
void signal_wake_up_state(struct task_struct *t, unsigned int state)
{
set_tsk_thread_flag(t, TIF_SIGPENDING);
/*
* TASK_WAKEKILL also means wake it up in the stopped/traced/killable
* case. We don't check t->state here because there is a race with it
* executing another processor and just now entering stopped state.
* By using wake_up_state, we ensure the process will wake up and
* handle its death signal.
*/
if (!wake_up_state(t, state | TASK_INTERRUPTIBLE))
kick_process(t);
}
这就是你如何做到的。请注意,设置线程标志是不够的:您必须使用唤醒功能来确保进程已安排。