3

OS X でのソケット同期に kqueue を使用しています。次のような目的のイベントを登録できます。

struct kevent change;
EV_SET(&change, connected_socket, EVFILT_READ, EV_ADD, 0, NULL, NULL);
kevent(k_queue_, &change, 1, NULL, 0, NULL);

問題は、このイベントを強制的にトリガーして、待機中の kevent 呼び出しが返されるようにする方法はありますか?

4

3 に答える 3

3

ソケットの反対側へのデータの自然な書き込み以外のいくつかの可能性:)

  • shutdown(2)そのソケットの読み取り側-あなたは(ばかげて)入るでしょEV_EOFflags
  • timeout 引数を使用して、同じ処理関数を呼び出します。
  • 待機を中断する必要がある場合は、セルフパイプ トリックを使用します。

私の質問ですが、なぜこれが必要なのですか?

編集:

私があなたのコメントを正しく理解していればEV_CLEAR、書き込みイベントのエッジ トリガー動作 ( ) を回避する方法を探しています。これを行う適切な方法は、発信キューに何もないときにソケットを登録EVFILT_WRITE解除し、送信するデータがあるときに再度登録することだと思います。もう少し手間がかかりますが、そのように動作しkevent(2)ます。変更と結果の両方を受け入れるため、追加のシステム コールは必要ありません。libeventこの種のものをどのように処理するかを調べてください。そして、あなたはノンブロッキングソケットを使用していますよね?

于 2010-07-28T16:08:08.717 に答える
2

少し異なる解決策をお勧めします。

別の登録済みイベントを kqueue に追加します。具体的には EVFILT_USER です。

これを使用して、コードが奇妙に見えたり保守が難しくなったりすることなく、 kevent() スレッドを起動したいあらゆる動作をトリガーできます。

OSXソースには、実際の大まかなテストがあります

http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/tools/tests/xnu_quick_test/kqueue_tests.c

于 2012-03-04T20:42:40.177 に答える
1

OSX 10.6 と FreeBSD 8.1EVFILT_USERでは、別のスレッドからイベント ループを起動するために使用できる のサポートが追加されています。

これを使用して独自の条件と timedwait を実装する場合でも、この優れた回答で説明されているように、競合状態を回避するためにロックが必要であることに注意してください。

完全なコード例については、私の他の回答を参照してください: https://stackoverflow.com/a/31174803/432

于 2015-07-02T07:40:15.987 に答える