空の Mach ポート セットという 1 つのアイテムを監視している kqueue があります。kevent64
利用可能なイベントがないことをselect
示し、kqueue が読み取りの準備ができていないことを示します。しかしpoll
、kqueueは読み取り可能であると言います! kevent64
- ただし、準備ができていると思われるイベントを後で読み取るために呼び出す場合は、そうではないようです。
私が使用しているコードは以下のとおりです。のようなものでビルドしてから、または何でもgcc -Wall -std=c99 -o test test.c
実行できます。(待機せずに 1 を読み取ろうとした後に実際に取得されたイベントの数)、(ポーリング後に読み取りの準備ができているファイル記述子の数)、および (ポーリング後に読み取りの準備ができているファイル記述子の数)./test
からの戻り値を出力します。kevent64
select
poll
私が期待する出力は次のようなもので、kqueue が空であることを示してkevent64
いますselect
。poll
$ ./kqueue_poll_machport
kevent64: 0
select: 0
poll: 0 (revents: 0)
kevent64: 0
しかし、私が実際に得たのはこれであり、それを示して、あることkevent64
をselect
言いpoll
、さらに、poll
kqueueが読み取り可能であることを示した後でも、読み取るイベントがないことを示しています(これが2番目の呼び出しkevent64
の理由です) kevent64
)。
$ ./kqueue_poll_machport
kevent64: 0
select: 0
poll: 1 (revents: 1)
kevent64: 0
( の 1 の値revents
はPOLLIN
、おそらく、ブロックせずにデータを読み取ることができることを示します。POLLRDNORM
と をPOLLRDBAND
個別に指定した場合、結果は同じです。)
なぜ不一致なのですか?
私のテストコード:
#include <stdio.h>
#include <assert.h>
#include <mach/mach.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <sys/select.h>
#include <poll.h>
int main(void) {
kern_return_t kr;
int rc;
int kq=kqueue();
assert(kq!=-1);
mach_port_name_t port_set;
kr=mach_port_allocate(mach_task_self(),MACH_PORT_RIGHT_PORT_SET,&port_set);
assert(kr==KERN_SUCCESS);
{
const struct kevent64_s events[]={
{
.flags=EV_ADD|EV_ENABLE,
.filter=EVFILT_MACHPORT,
.ident=port_set,
},
};
rc=kevent64(kq,events,sizeof events/sizeof events[0],NULL,0,0,NULL);
assert(rc==0);
}
/* Events available? */
{
const struct timespec NO_TIMEOUT={0,0};
struct kevent64_s event;
rc=kevent64(kq,NULL,0,&event,1,0,&NO_TIMEOUT);
printf("kevent64: %d\n",rc);
}
/* Test readability with select. */
{
const struct timeval NO_TIMEOUT={0,0};
fd_set rd;
FD_ZERO(&rd);
FD_SET(kq,&rd);
rc=select(kq+1,&rd,NULL,NULL,&NO_TIMEOUT);
printf("select: %d\n",rc);
}
/* Test readibility with poll. */
{
struct pollfd fds[]={
{
.fd=kq,
.events=POLLIN,
},
};
rc=poll(fds,sizeof fds/sizeof fds[0],0);
printf("poll: %d (revents: %d)\n",rc,fds[0].revents);
}
/* Events available? */
{
const struct timespec NO_TIMEOUT={0,0};
struct kevent64_s event;
rc=kevent64(kq,NULL,0,&event,1,0,&NO_TIMEOUT);
printf("kevent64: %d\n",rc);
}
}