libeventのソースコードから(v2.0.19-安定)
/ * signal.c
これは、信号処理を行うためのより良い方法がないバックエンドに使用する信号処理の実装です。sigaction()またはsignal()を使用してシグナルハンドラーを設定し、ソケットペアを使用してイベントベースにいつ通知するかを指定します
「イベントベース」と言ったことに注意してください。これを使用するために一度に設定できるイベントベースは1つだけです。歴史的な理由と下位互換性のために、信号のイベントをevent_base Aに追加してから、信号のイベント(任意の信号!)をevent_base Bに追加すると、event_base Bは信号について通知されますが、event_baseAは通知されません。 。
Libeventの将来のバージョンでこの動作を変更するのは良いことです。kqueueはすでにはるかに賢明なことをしています。 Signalfdを使用して、Linux上のすべてのバックエンドに妥当な処理を実行させることができます。
* /
そのため、現在、libeventはsigaction()が使用可能な場合はそれを使用し、それが失敗した場合はsignal()を使用します。
signalfd()を使用する場合は、通常、sigprocmaskを使用してシグナルをブロックし、シグナルによってデフォルトのハンドラーが実行されないようにします。次に、libeventを使用して返されたファイルハンドルを監視し、メモリの安全性や他のシステムコールのブロックや中断を心配することなく、通常の同期コードからのシグナルを安全に処理できます。
従来の非同期シグナルハンドラー(つまり、sigactionを使用して登録されたもの)内で安全に実行できることには制限があります。mansignalの「Async-signal-safefunctions」を参照してください。signalfdアプローチを使用すると、これらの制限が大幅に緩和されます。
libeventは非常に多くのプラットフォームをサポートしており、少なくとも1人が問題を報告したため、タイマーコールバックの登録に関する警告が懸念事項として提示された可能性があります。signalfdによって登録されたファイルハンドルを選択/ポーリングする場合は、とにかくこの制限について心配する必要はないことに注意してください。
編集:私はあなたの質問を読み直しました、そして私が本当にそれに正しく答えていなかったことに気づきました。signalfdを登録し、それをlibeventで使用する利点は、移植性を犠牲にして高速になるためです。signalfdをlibeventに含める計画(http://archives.seul.org/libevent/users/Mar-2010/msg00046.html)がありましたが、まだ実現していません。
また、SIGCHLDの通知を受け取ったら、ENOCHLDを取得するまで、常にループ内でwaitpidを呼び出す必要があります。これは、両方のメソッドがシグナルの複数のオカレンスを折りたたむためです。