信号(特にSIGUSR1 / SIGUSR2 / SIGSTOP)を介してオペレータと通信するアプリケーションがあります。
何が起こっても、すべての信号がハンドラによって転送され処理されると信じることができますか?
アプリケーションが処理できるよりも速く信号が送信された場合(たとえば、現在のホスト負荷が高いため)はどうなりますか?
答え1
「あまりにも多くの信号」の問題に加えて、明示的に信号を無視することも可能です。 ~からman 2 signal
:
If the signal signum is delivered to the process, then one of the
following happens:
* If the disposition is set to SIG_IGN, then the signal is ignored.
信号も遮断できます。 ~からman 7 signal
;
A signal may be blocked, which means that it will not be delivered
until it is later unblocked. Between the time when it is generated
and when it is delivered a signal is said to be pending.
ブロックおよび無視された信号のセットは子プロセスに継承されるため、アプリケーションの親プロセスはこれらの信号のいずれかを無視またはブロックできます。
プロセスが以前の信号処理を完了する前に複数の信号が転送された場合はどうなりますか?これはオペレーティングシステムによって異なります。上記のマンページではsignal(2)
これについて説明します。
- System V は信号処理をデフォルト値にリセットします。さらに悪いことに、複数の信号をすばやく転送すると再帰(?)呼び出しが発生することがあります。
- BSDはハンドラが完了するまで自動的に信号をブロックします。
- Linux では、GNU に設定されたコンパイルフラグによって異なりますが、
libc
BSD の動作が予想されます。
答え2
あなたが送るすべての信号が伝わると信じることはできません。例えば、LinuxカーネルはSIGCHLDを「マージ」します。プロセスが子プロセスを終了する SIGCHLD を処理するのに長い時間がかかる場合。
質問の他の部分に答えると、短すぎる時間に多くの異なる信号が到着すると、信号がカーネル内に「待機」される可能性があります。
メンバーを使用してsigaction()
シグナルハンドラーを設定し、メンバーのパラメーターを慎重に設定する必要があります。私はこれが少なくともすべての「非同期」信号をブロックすることを意味すると思います。 Linuxのマニュアルページによれば、処理中の信号もマスクします。メンバーをSA_SIGINFOに設定する必要があるようですが、なぜこのような迷信があるのか覚えていません。私はこれがあなたのプロセスが競合状態なしで設定された状態を維持し、他のほとんどの信号によって中断されない信号ハンドラを得ることができると信じています。sa_sigaction
siginfo_t
sa_mask
siginfo_t
sigaction()
sa_flags
信号処理機能を非常に慎重に作成してください。デフォルトでは、信号がキャプチャされたことを示すためにグローバル変数を設定し、プロセスの残りの部分がその信号に必要なものを処理するようにします。これにより、できるだけ短い時間にわたって信号がブロックされます。
また、信号処理コードを非常に徹底的にテストする必要があります。これを小規模テストプロセスに適用し、2〜3個の専用信号トランスミッタからできるだけ多くのSIGUSR1およびSIGUSR2信号を送信します。コードがSIGUSR1とSIGUSR2をすばやく正確に処理できることを確認すると、他の信号を混在させることができます。難しいデバッグに備えてください。
signalfd()
Linuxを使用してLinuxのみを使用している場合は、それを使用してファイル記述子を生成するか、select()
これらの信号を受信するためにポーリングすることを検討できます。を使用すると、signalfd()
デバッグが簡単になります。
答え3
kill
プロセスが正常に呼び出されると、ターゲットがシグナルを受信するという意味でシグナリングが保証されます。これは非同期です。発信者は、信号がいつ受信されるか処理されるかを知ることができない。しかし、これはシグナル伝達を保証しません。信号が処理される前にターゲットが死ぬ可能性があります。ターゲットがシグナルを送信するときにシグナルを無視すると、シグナルは何の効果もありません。信号を処理する前に、ターゲットが同じ信号番号の複数のインスタンスを受信すると、信号はマージされ、しばしばマージされます。同じ信号をプロセスに2回送信する場合、プロセスが信号を1回または2回受信するかどうかを知る方法はありません。 。信号は主にプロセスを終了したり、プロセスに注意を払うように設計されており、通信自体のために設計されていません。
安定した配信が必要な場合は、他の通信メカニズムが必要です。プロセス間には2つの主要な通信メカニズムがあります。管路一方向の通信を許可します。ソケット双方向通信と同じサーバーへの複数の接続を許可します。送信数だけ通知を処理するために宛先が必要な場合は、パイプを介してバイトを送信してください。
答え4
ブロック中に複数の標準信号が転送されると、カーネルは標準信号を自由にマージできます。一方、リアルタイム信号には同じ欠点はありません。
リアルタイム信号には次の特徴があります。
- リアルタイム信号の複数のインスタンスをキューに含めることができる。対照的に、その信号が現在ブロックされている間に標準信号の複数のインスタンスが転送されると、1つのインスタンスのみがキューに追加されます。
SIGRTMINからSIGRTMAXの範囲の数字を含む信号を試してください。