2016-10-02 9 views
0

私はSIGINTハンドラを持っています。プログラム全体の変数を設定します:errflagselect()を実行してSIGINTで中断した場合、errflagをチェックしてSIGINTerrflagに割り当てられた独自の定数を持つ)かどうかを確認します。ただし、ハンドラが遅くなり、errflagがまだ設定されていない可能性があります。ハンドラの解決前に処理を延期する方法はerrflag?またはこれを正しく実装する方法は?シグナルハンドラが確実に終了してからプログラムを続行する方法を確認するには?

select()は、Ctrl-Cの-1を返します。errnoは、EINTRです。ここでハンドラは決して遅くはない。他のパスでselect()-1errnoEINTRの場合でも、少し遅れてログメッセージが出力され、遅い場合はerrflagチェックが既に実行されています。

+0

最初の答えで指摘したように、割り込みは現在の処理を停止してハンドラを実行し、ハンドラが返ってくるとシステムコールを再起動するか、 'errno'を' EINTR'に設定して割り込みを中断します。あなたは 'signal()'や 'sigaction()'を使っていますか?あなたのコードがないと、何がうまくいかないのか分かりにくいですが、シグナルハンドラが「遅延」する可能性があるという解釈は基本的には間違っています。 'sigaction()'では、別のシグナルが 'sa_mask'で処理されている間にシグナルをブロックすることができますが、ブロックされたシグナルは最初のハンドラが返ったときに配信されます。 –

+0

@JonathanLeffler:はい、あなたは正しいです。シグナルはキューメカニズムによって手動で遅延され、ハンドラの早期復帰、その前にデバッグされず、最初から最後の呼び出しとしてfrom-queueコールが解釈されます。 – Itzie

+0

したがって、2つ以上の出口ルートを持つシグナルハンドラがあり、1つは診断プリントが施されていて、もう1つは実行されていませんでしたか?簡単に行うことができますが、見るべきこともあります。結果が深刻に誤解される可能性があります。 'シングルエントリー、シングル出口'プログラミングのメリットの1つは、あなたがその問題にぶつからないということです! –

答えて

3

ただし、ハンドラが遅く、errflagがまだ設定されていない可能性があります。

何か?いいえ、「遅れる」ことはできません。他の何かが間違っています。

シグナルハンドラは通常のプログラムフローを中断します - シグナルハンドラが終了すると、SIGINTが受信されたときにハンドラが実行され、制御フローが残りのプログラムにのみ解放されます。

errflagvolatileと宣言されていることを確認する必要があるため、コンパイラはその値がいつ変更できるかについて過度の前提をしません。

printf()は、信号処理中に矛盾した状態になる可能性があるグローバルバッファを使用する可能性があるため、シグナルハンドラでは安全ではありません。 Generally speaking, very few things are safe to do during a signal handler besides setting volatile global variables or exiting.printf()をシグナルハンドラで使用しようとすると、結果が矛盾して混乱することがあります。あなたのプログラムで実際に何が起こったのかを信頼できる指標として出力を使用すべきではありません!

+0

ありがとう、私は確認して、ハンドラは即座に呼び出され、キューのメカニズムだけがあり、信号は後でキューから何とか再起動されます。可能性のあるキューイングの後で、後でデバッグメッセージを表示していましたが、瞬時オン信号ハンドラ呼び出しを確認できませんでした。 – Itzie

関連する問題