10

たとえば、アプリケーションがキャンセル ポイントでブロックされ、readシグナルが受信され、シグナル ハンドラが呼び出されたとします。Glibc/NPTL は、syscall の実行中に非同期キャンセルを有効にすることでキャンセル ポイントを実装しているため、私が知る限り、非同期キャンセルはシグナル ハンドラーの実行中に有効なままになります。もちろん、これはひどく間違っています。非同期キャンセルセーフではないが、シグナルハンドラーから安全に呼び出す必要がある関数がたくさんあるからです。

これにより、2 つの質問が残ります。

  • 私は間違っていますか、それとも glibc/NPTL の動作は本当に危険なほど壊れているのでしょうか? もしそうなら、そのような危険な行動は準拠していますか?
  • POSIX によると、プロセスがキャンセル ポイントである関数を実行しているときにシグナル ハンドラが呼び出された場合、どうなるでしょうか。

編集:pthread_cancel潜在的なターゲットであるスレッドは、キャンセルポイントである関数がそのスレッドのコンテキストでシグナルハンドラーから呼び出されないようにする必要があることをほぼ確信しています:

一方では、キャンセルされる可能性があり、async-cancel-unsafe 関数を使用するスレッドで呼び出すことができるシグナル ハンドラーは、キャンセル ポイントである関数を呼び出す前にキャンセルを無効にする必要があります。これは、シグナルによって割り込まれたコードの観点からは、そのようなキャンセルは非同期キャンセルと同等であるためです。一方、シグナル ハンドラーは、非同期シグナル セーフではないため、シグナル ハンドラーが呼び出されたときに実行されるコードが非同期シグナル セーフ関数のみを使用しない限り、取り消しを無効にすることはできませpthread_setcancelstateん。

4

3 に答える 3

4

私自身の質問の前半に答えるために:glibcは私が予測した振る舞いを示します。キャンセルポイントでブロックされている間に実行されるシグナルハンドラーは、非同期キャンセルで実行されます。この効果を確認するには、永久に(または長時間)ブロックするキャンセルポイントを呼び出すスレッドを作成し、しばらく待ってからシグナルを送信し、もう一度しばらく待ってからキャンセルして参加します。シグナルハンドラーは、非同期で終了する前に予測できない時間実行されたことを明確にする方法で、いくつかの揮発性変数をいじる必要があります。

POSIXがこの動作を許可するかどうかについては、まだ100%確実ではありません。POSIXの状態:

スレッドでキャンセル可能性が有効になっていて、そのスレッドをターゲットとしてキャンセル要求が行われ、スレッドがキャンセルポイントである関数(pthread_testcancel()やread()など)を呼び出す場合は常に、キャンセル要求が実行されます。関数が戻る前に。スレッドでキャンセル可能が有効になっていて、キャンセルポイントでスレッドが中断されているときにスレッドをターゲットとしてキャンセル要求が行われた場合、スレッドはウェイクアップされ、キャンセル要求が実行されます。次の場合、キャンセル要求が実行されるかどうか、またはキャンセル要求が保留されたままでスレッドが通常の実行を再開するかどうかは指定されていません。

  • スレッドはキャンセルポイントで中断され、待機中のイベントが発生します

  • 指定されたタイムアウトが期限切れになりました

キャンセルリクエストが処理される前。

おそらく、シグナルハンドラーの実行は「一時停止」の場合ではないので、ここではglibcの動作を不適合として解釈することに傾倒しています。

于 2011-04-20T04:18:32.360 に答える
0

あなたが探しているのは、次の2つの組み合わせだと思います。

EINTR一部のシステム コールは、エラーが返される原因となるシグナルによって中断される場合があります。これは正常な動作ですが、たとえば、readストリームから何も読み取られない場合に何が起こるかについては明確にしていません。おそらく、誰かがこれについてコメントして、明確にするのを助けることができます。

あなたが心配しているように、中断されるべきではないシステムコールは、中断されないようにするために、への呼び出しsigprocmask(またはpthread_sigmaskスレッド) でラップする必要があります。シグナルを再度有効にすると、ブロックされている間に受信したシグナルが配信されます。ただし、割り込みと同様に、ブロックが長すぎると、上書きにより一部が失われる可能性があります (同じシグナルを複数回受信すると、保留中のシグナルが 1 つとしてカウントされます)。

于 2011-03-23T19:25:28.383 に答える