1

空の Mach ポート セットという 1 つのアイテムを監視している kqueue があります。kevent64利用可能なイベントがないことをselect示し、kqueue が読み取りの準備ができていないことを示します。しかしpoll、kqueue読み取り可能であると言います! kevent64- ただし、準備ができていると思われるイベントを後で読み取るために呼び出す場合は、そうではないようです。

私が使用しているコードは以下のとおりです。のようなものでビルドしてから、または何でもgcc -Wall -std=c99 -o test test.c実行できます。(待機せずに 1 を読み取ろうとした後に実際に取得されたイベントの数)、(ポーリング後に読み取りの準備ができているファイル記述子の数)、および (ポーリング後に読み取りの準備ができているファイル記述子の数)./testからの戻り値を出力します。kevent64selectpoll

私が期待する出力は次のようなもので、kqueue が空であることを示してkevent64いますselectpoll

$ ./kqueue_poll_machport
kevent64: 0
select: 0
poll: 0 (revents: 0)
kevent64: 0

しかし、私が実際に得たのはこれであり、それを示して、あることkevent64select言いpoll、さらに、pollkqueueが読み取り可能であることを示した後でも、読み取るイベントがないことを示しています(これが2番目の呼び出しkevent64の理由です) kevent64)。

$ ./kqueue_poll_machport
kevent64: 0
select: 0
poll: 1 (revents: 1)
kevent64: 0

( の 1 の値reventsPOLLIN、おそらく、ブロックせずにデータを読み取ることができることを示します。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);
    }
}
4

0 に答える 0