2

これは、私がここで見つけた関連する質問のフォローアップ です。

リンクされた質問には、libeventsignalfd()でそのfdを使用および使用することについての言及があります。その質問では、OPは、libevent信号処理機能とは対照的に彼が使用している理由をリストしていません。signalfd()

どちらの方法でも、シグナルハンドラーの外部でコールバックを処理します。

このドキュメントは、シグナルイベントコールバックでのタイマーのスケジューリングについて警告しているようです。これは正しくないようです(シグナルハンドラコンテキストの外にいるため)。上記の警告は別として、これをで行うことの利点はわかりませんsignalfd()

2つの方法の違いまたは警告に関する入力

ありがとう!

4

1 に答える 1

2

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を呼び出す必要があります。これは、両方のメソッドがシグナルの複数のオカレンスを折りたたむためです。

于 2012-05-09T08:12:50.170 に答える