2011-12-21 10 views
0

私のアプリケーションでセマフォーを見ましたwere not always working as expected。次に、信号がsem_waitコールを中断したときに、この予期しない動作が発生する可能性があると言われました。シグナルがある場合にはどうすればいいですか

私の質問は、信号の存在下でプログラマがどのような注意を払う必要があるかということです。 sem_waitについては、戻り値を確認できますが、これはすべての非同期安全関数で同じですか?そして、シグナルがコードを中断することを期待しているときは、何を覚えておくべきですか?

答えて

2

UNIXシグナルはワームの缶であり、ちょうどそれを言いました。

システムコールと信号に関する2つのキャンプがあります。

  • SysVの/ POSIXセマンティクスは:システムコールがシグナルによって中断されている、彼らはエラーを返し、EINTR
  • をerrnoに設定し
  • BSDのセマンティクスのシステムコール信号は、いくつかの、(よく、それらのほとんどは、とにかくある発生した場合、自動で再起動されますそうではない、例えば、選択/ポーリング/スリープ)。

signal()を使用する場合、デフォルトは上記の2つのうちの1つで、BSDセマンティクスにデフォルト設定されたLinuxとBSDセマンティクスにデフォルト設定されているLinuxです。 (Linuxでは、これは例えば-std = c99を使用してコンパイルすると、-std = gnu99はBSDのセマンティクスを与えると、SysVのセマンティクスを与え、多くのものに依存します。例えばhttp://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.htmlを参照してください)

あなたははsigactionとシグナルハンドラを(インストール時)、 SA_RESTARTフラグを使ってどのセマンティクスを選択するかを決定します。

基本的には:

  • あなたはそれを助けることができるかどうかの信号を使用しないでください。
  • 可能であれば、BSDセマンティクスを使用してください。
  • 移植性があり、シグナルを処理するコードでは、呼び出しごとにエラーをチェックし、EINTRのerrnoを検査して、システムコールを再度実行するループ内のすべてのシステムコールをラップする必要があります(または、シグナル)。
  • あなたのコードではなくても、ライブラリ呼び出しはシグナルを使用できます。
  • 一般に、SysV/Posixのセマンティクスを持つシステムコールは-1を返し、errnoにEINTRを設定します。しかし、エラー状態が何であるかを知るためには、文書を読んでください。

EDIT:私はBSDとSysvのセマンティクスを混ぜて編集しました。

+0

SysVが自動でシステムコールを再起動すると、エラーコードを与えることがあるため、sem_waitが再起動しないのはなぜですか? – MetallicPriest

+0

@ MetallicPriestあなたは100%確実ではありませんか?とにかく、sysvのセマンティクスであっても、自動再起動されないシステムコールのリストがあったといいです。 sem_waitはその1つかもしれません。 – user964970

+0

任意のシステムコールのデフォルトの割り込みアクションは、システムのマンページに記録されていなければなりません。 Linuxシステムを使用していて、何も異常を起こさなかった場合、システムコールはシグナルによって中断された後、透過的に再起動されます。 –

関連する問題