2013-08-05 7 views
5

Мое понимание заключается в следующем:Как системные вызовы прерываются сигналом?

блокирующий системный вызов обычно помещает процесс в государстве «TASK_INTERRUPTIBLE», так что, когда сигнал подается, ядро ​​помещает процесс в состояние «TASK_RUNNING». И процесс будет запланирован для запуска, когда произойдет следующий тик таймера, так что syscall будет прерван.

Но я сделал небольшое испытание, оно потерпело неудачу. Я worte процесс usermode, который называется sleep(). И я изменил состояние процесса на TASK_RUNNING в ядре, но sleep() не был прерван вообще, и процесс все еще спал.

Затем я попробовал wake_up_process (process), это не удалось.

Затем я попробовал set_tsk_thread_flag (процесс, TIF_SIGPENDING), он не прошел.

Затем я попробовал set_tsk_thread_flag (процесс, TIF_SIGPENDING) и wake_up_process (process), успешно! sleep() был прерван, и процесс начал работать.

Так что все не так просто. Кто-нибудь знает, как именно системные вызовы прерываются сигналом?

+0

Если вы просто вызываете 'wake_up_process()', тогда процесс просыпается, проверяет, что происходит, и обнаруживает, что нет причин проснуться, поэтому он сразу возвращается к сна. Если вы просто установите флаг без пробуждения процесса, то он не проснется, поэтому не проверяет флаг. Вам нужно сделать то и другое. – caf

ответ

2

Отъезд __send_signal от signal.c. Он называет 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); 
} 

И это, как вы это делаете. Обратите внимание, что установить флажок потока недостаточно: вам нужно использовать функцию пробуждения, чтобы гарантировать, что процесс запланирован.

+0

, я попробовал wake_up_process() без установки флага потока, это тоже не сработало. Поэтому я хочу, когда и как системные вызовы прерываются сигналом? – goodjesse

+0

... вы устанавливаете флаг потока, затем вы пробуждаете процесс. Пропустите любой из этих двух шагов, и это не сработает. Что непонятно? – nneonneo

Смежные вопросы