5

私の理解は次のとおりです。

ブロッキング syscall は通常、プロセスを「TASK_INTERRUPTIBLE」状態にするため、シグナルが配信されると、カーネルはプロセスを「TASK_RUNNING」状態にします。そして、次のタイマーティックが発生したときにプロセスが実行されるようにスケジュールされるため、syscall は中断されます。

しかし、私は小さなテストを行いましたが、失敗しました。sleep() を呼び出すユーザーモード プロセスを書きました。そして kernel でプロセスの状態を TASK_RUNNING に変更しましたが、 sleep() はまったく中断されず、プロセスはスリープ状態のままでした。

次に、 wake_up_process(process) を試しましたが、失敗しました。

それから set_tsk_thread_flag(process,TIF_SIGPENDING) を試しましたが、失敗しました。

次に、set_tsk_thread_flag(process,TIF_SIGPENDING) と wake_up_process(process) を試してみましたが、成功しました!! sleep() が中断され、プロセスが実行を開始しました。

それほど単純ではありません。システムコールが signal によってどのように中断されるかを知っている人はいますか?

4

1 に答える 1

2

からチェックアウト__send_signalsignal.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);
}

そして、それがあなたのやり方です。スレッド フラグを設定するだけでは不十分であることに注意してください。プロセスがスケジュールされていることを確認するには、ウェイクアップ関数を使用する必要があります。

于 2013-08-05T12:12:00.790 に答える