3

シングル プロセッサのシナリオを考えてみましょう。

wait_event_interruptible()(または他の待機 API) は、特定の条件が満たされるまでループで待機します。

現在、Linux には個別のプロセスとして実装されているスレッドがあるため、偽のウェイク (wait_event*条件が満たされていない状態でウェイクアップされる) は、プログラム/ドライバーのエラーを示していると思います。

私が間違っている?- そのような誤ったウェイクが発生し、使用される有効なシナリオはありますか? 言い換えれば、なぜ実装のループで条件を待つのでしょうか?wait_event*

4

3 に答える 3

8

待機キューの一般的な使用例は、割り込みです。おそらく、カーネル ドライバーは現在 3 つの異なる条件で待機しており、それぞれが割り込みで起動されます。

これにより、カーネル割り込みハンドラーがすべてのリスナーを起動するだけで済み、特定の条件が発生したかどうか、または起動する必要があるかどうかをリスナー間で判断できます。

また、割り込みが共有される可能性があり、割り込みが遅延および合体されるため、偽の割り込みが発生する可能性があります。


いくつかのコードを追加し、より明示的にしようとしないもの。

以下に、カーネル ドライバーの一部である可能性のあるコードをいくつか書きました。割り込みハンドラーは、単純にすべてのリスナーを起動します。ただし、実際にはすべてのリスナーが完了するわけではありません。どちらも同じ割り込みによって起こされますが、続行する前に特定の条件が満たされているかどうかを確認します。

// Registered interrupt handler
static irqreturn_t interrupt_handler(void *private) {
    struct device_handle *handle = private;
    wake_up_all(&handle->wait);
}

// Some Kernel Thread
void program_a(struct device_handle * handle) {
    wait_event_interruptible(&handle->wait, hardware_register & 0x1);
    printk("program_a finished\n");
}

// Some other kernel thread
void program_b(struct device_handle * handle) {
    wait_event_interruptible(&handle->wait, hardware_register & 0x2);
    printk("program_b finished\n");
}
于 2012-06-26T02:22:46.743 に答える
3

コード:

#define __wait_event(wq, condition)                     \
do {                                    \
    DEFINE_WAIT(__wait);                        \
                                    \
    for (;;) {                          \
        prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
        if (condition)                      \
            break;                      \
        schedule();                     \
    }                               \
    finish_wait(&wq, &__wait);                  \
} while (0)

(カーネルがプリエンプティブであるという事実に加えて...)

上記の無限の「for」ループについて言及していると思いますか?もしそうなら、それがそこにある主な理由はこれです:

コードは、起動後の状態について何も仮定しません。目が覚めただけでは、待っていたイベントが実際に発生したわけではありません。再確認する必要があります。それはまさにループが達成するものです。「if」条件が真になると (通常はそうなるはずです)、ループを終了します。

于 2012-06-26T02:13:47.140 に答える
0

シングル プロセッサのシナリオでも、カーネルはプリエンプティブです。つまり、制御はいつでも他のスレッド/プロセスに渡すことができるため、動作はマルチプロセッサと同じです。ロストウェイトの問題に関する良い議論はここにあります: http://www.linuxjournal.com/node/8144/print

于 2012-06-25T10:47:12.570 に答える