4

私は Linux を初めて使用し、Rubini & Corbet による Linux デバイス ドライバーの本を読んでいます。に関連する 1 つのステートメントで混乱していspinlocksます。本の状態

非プリエンプティブ ユニプロセッサ システムがロックでスピンに入った場合、永久にスピンします。他のスレッドが CPU を取得してロックを解放することはできません。このため、プリエンプションが有効になっていないユニプロセッサ システムでのスピンロック操作は、IRQ マスキング ステータスを変更するものを除いて、何もしないように最適化されています。

さらに本の状態

カーネル プリエンプションのケースは、スピンロック コード自体によって処理されます。カーネル コードがスピンロックを保持している場合は常に、関連するプロセッサでプリエンプションが無効になります。単一プロセッサ システムでも、競合状態を回避するために、この方法でプリエンプションを無効にする必要があります。

質問 : ユニプロセッサ システムで、カーネル コード (ユーザー プロセスに代わって実行) がスピンロックを保持するたびにカーネル プリエンプションが無効になっている場合、別のプロセスが実行する機会を得て、スピンロックを取得しようとする可能性はありますか? カーネル コードがスピンロックを保持するたびに Linux カーネルがカーネル プリエンプションを無効にするのはなぜですか?

4

4 に答える 4

9

最初の質問に対する答えは、2 番目の理由です。

カーネルが取得したスピンロックは、プリエンプションをオフにすることで実装できます。これにより、カーネルが別のプロセスに干渉することなくクリティカル セクションを完了することが保証されるためです。全体的なポイントは、カーネルがロックを解放するまで、別のプロセスを実行できないということです。

このように実装しなければならない理由はありません。それを実装する簡単な方法であり、カーネルが保持するロックでプロセスが回転するのを防ぎます。しかし、このトリックは、カーネルがロックを取得した場合にのみ機能します。ユーザー プロセスはプリエンプションをオフにできず、カーネルがスピンしている場合 (つまり、スピンロックを取得しようとしたが、別のプロセスが既にそれを保持している場合) は、プリエンプションをそのままにしておく方がよいでしょう。の上!そうしないと、カーネルがロックを保持しているプロセスがロックを解放できないために解放されないロックを待っているため、システムがハングします。

スピンロックを取得するカーネルは特殊なケースです。ユーザー レベルのプログラムがスピンロックを取得した場合、プリエンプションは無効になりません。

于 2013-08-15T15:09:20.253 に答える
1

プロセス A とプロセス B の両方が同じデータにアクセスするため、SPIN LOCK を定義します。A がロックを保持しているが、プリエンプションを有効のままにしている場合。その場合、A は欠場する可能性があり、B には実行のチャンスがあります。B がロックを取得しようとした場合。B はスピンして CPU を浪費します。

スピンロックは、効率を高め、小さくて高速なクリティカル ゾーンを保護するように設計されています。スピンブロックはプリエンプションを無効にします。ロックしたいがプリエンプションを有効にしたままにする場合。ミューテックスロックを使用できます。

プロセス A がロックを解除すると、プリエンプションが再び有効になります。そのため、他のプロセスが実行される可能性があります。それ以前は、ハードウェア割り込みとソフトウェア IRQ のみが実行できます。

于 2019-10-24T02:40:45.283 に答える