我的理解如下:
阻塞系统调用通常将进程置于“TASK_INTERRUPTIBLE”状态,以便在传递信号时,内核将进程置于“TASK_RUNNING”状态。 当下一个计时器滴答发生时,进程将被安排运行,以便系统调用被中断。
但是我做了一个小testing,失败了。 我运行一个名为sleep()的用户模式进程。 我在内核中将进程的状态改为TASK_RUNNING,但是sleep()完全没有中断,进程还在hibernate。
然后我尝试wake_up_process(进程),它失败了。
然后我尝试set_tsk_thread_flag(进程,TIF_SIGPENDING),它失败了。
然后我尝试了set_tsk_thread_flag(process,TIF_SIGPENDING)和wake_up_process(process),成功了! sleep()被中断,进程开始运行。
所以并不是那么简单。 有谁知道系统调用如何被信号中断?
检查__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); }
这就是你如何做到的。 请注意,设置线程标志是不够的:您必须使用唤醒功能来确保进程已安排。