1

でkqueueを作成するとkqueue()、ファイル記述子が返されます。しかし、このファイル記述子は で意味のあるポーリングを行うことができないようselect()です。からポーリング/読み取りを行う標準的なkqueue()方法はを使用していることを理解していkevent(...)ますが、 を使用してファイル記述子をポーリングするレガシー コードと統合しようとしていますselect()

ここでの目標は、このベースのポーリング メカニズムで検出できる「ユーザー イベント」を起動できるようにすることでしたselect(イベントを後で使用して「消費」する必要がある場合でもkevent())。EVFILT_USERこれは、この種のことを行うために生まれたように見えましたが、簡単な実験ではselect()、イベントが kqueue に追加 (およびトリガー) されたときに、kqueue の fd が読み取り可能であると報告されず、タイムアウト (またはブロック) するだけであることが示されています。永遠に)。(しかし、同等のkevent()呼び出しイベントを参照/返します。)

私は何か間違ったことをしていますか?それとも、kqueue の fd を でポーリングすることはできませんselect()か?

4

1 に答える 1

3

kqueue/kevent を説明している紙には、次のように書かれています (セクション 6.5):

通常のファイル記述子は kqueue を参照するため、記述子に対して通常実行できるすべての操作に参加できます。アプリケーションは、select()、poll()、close()、または kqueue を参照する kevent を作成することさえできます。

これは実際に FreeBSD の場合です。次のコードでこれを確認しました。

  struct kevent e;
  fd_set fdset;
  int kq=kqueue();

  EV_SET(&e, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
  kevent(kq, &e, 1, 0, 0, 0); // register USER event filter

  EV_SET(&e, 1, EVFILT_USER, EV_ADD, NOTE_TRIGGER, 0, NULL);
  kevent(kq, &e, 1, 0, 0, 0); // trigger USER event

  FD_ZERO(&fdset);
  FD_SET(kq,&fdset);

  select(FD_SETSIZE,&fdset, 0, 0, 0); // wait for activity on kq

  int res = kevent(kq, 0, 0, &e, 1, 0); // get the event
于 2015-09-03T20:39:21.923 に答える