私は通常、信号がどのように機能するかを理解し、システムコールが作業状態を変更したり、重要なセクションで信号割り込みを防止したりすることを理解していTASK_INTERRUPTIBLE
ますTASK_UNINTERRUPTIBLE
。これでTASK_INTERRUPTIBLE
、作業状態があり、システムコール中に信号がキャプチャされた場合に何が起こるのかを理解したいと思います。
私の質問は次のとおりです。
システムコールの実装(例
read()
:)がシグナルを処理する方法。たとえば、read()
ext2ファイルシステムドライバの読み取り機能の内部にあるとします。この機能は信号が発生するたびに確認しますか?割り当てたリソースを解放するか、取得したロックを解放する必要があるためです。全体的に私の質問は、システムコールの実装(カーネルとドライバでさまざまな機能を呼び出すことに関連して)がシグナルが発生したことをどのように知って割り当てられたリソースを解放するかです。システムコールがミューテックスが利用可能になるのを待っていて(タスクがブロックされている)シグナルが発生した場合、カーネルはミューテックスがロックされていませんが、シグナルが発生したことを
lock()
コール関数に通知しますか?read()
ext2ドライバで関数の実行中に信号が発生すると仮定します。 VFSレイヤとメインシステムコール機能(read()
)は、ext2ドライバの読み取り機能が信号のために失敗したことをどのように知っていますか?必要な検査をすべて受けましたか?確認すべきことはあまりありませんか?
答え1
システムコールの実装(例:read())がシグナルを処理する方法。
まあ、これは誤解の一部かもしれません。私たちはしばしばシステムコールについて同じように話しますが、実際にはユーザー空間インタフェースは通常stdlibを介して実装されています。カーネル空間の一部、つまりシステムコール操作を実行する部分は、カーネルコードを実行するカーネルスレッドです。カーネルスレッドは、ユーザー空間スレッドと同じ規則に従わず、シグナルがキューに追加され、マージされ、転送されない可能性があります。
...たとえば、read()の場合は、ext2ファイルシステムドライバの読み取り関数の内部にあるとします。この機能は信号が発生するたびに確認しますか?割り当てたリソースを解放するか、取得したロックを解放する必要があるためです。全体的に私の質問は、システムコールの実装(カーネルとドライバでさまざまな機能を呼び出すことに関する)がシグナルが発生したことをどのように知って割り当てられたリソースを解放するかです。
ファイルシステムコードは信号なしでカーネルスレッドとして実行されるため、必要ありません。いずれにせよ、システムコールは、カーネル操作を即座にトリガーせず、ワーカースレッドが完了するためにキューに入れる可能性が高くなります。この場合、スレッドは通常、I / Oが完了するのを待っている間信号を処理します。これは割り込み可能な動作です。これは、システムコールが実行されるコンテキスト外のユーザー空間で発生します。カーネルスレッドは、奇妙なコンテキストで保存して復元するのが複雑なため、システムコールに部分的に応答しません。
システムコールがミューテックスが使用可能になるのを待っていて(タスクがブロックされている)シグナルが発生した場合、カーネルはミューテックスのlock()呼び出し関数にロックされていませんが、シグナルが発生したことをどのように知らせますか?
シグナルがキューにあるカーネル空間では、これは起こらないでください。安全でない条件からユーザー空間コードを保護するために信号を使用することが重要であるため、問題であるかどうか、解決策を決定するためにアプリケーションを作成する必要があります。
ext2 ドライバの read() 関数の実行中に信号が発生すると仮定します。 VFS層と基本的なシステムコール関数(read())は、ext2ドライバの読み取り機能がシグナルのために失敗したことをどのように知っていますか?必要な検査をすべて受けましたか?確認すべきことはあまりありませんか?
カーネルプロセスがシグナルに応じて機能しないため失敗しないため、そうではありません。シグナルを受信したユーザー空間プロセスに制御が返されるまで、キューに入れられます。
また見なさい:
これは詐欺かもしれません。