несколько epoll_wait в разных потоках получают события, предназначенные не для них - PullRequest
0 голосов
/ 15 декабря 2011

У меня два вызова event_wait.
Поток 1: прослушивание каналов от дочерних процессов

        struct epoll_event *ev;
        struct EpollStub stub[pool->plugins.count];
...
        epollfd = epoll_create1(0);
        if (epollfd == -1) {
                return -1;
        }
        ev->events = EPOLLIN;
        for(int i=0;i<plugins->count;i++) {
             inf = &plugins->stp[i];
             stub[i].type = EREAD_STAP;
             stub[i].pointer = inf;
             ev->data.ptr = stub+i;
             if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, inf->fd, ev) == -1) {
                 close(epollfd);
                 return -1;
             }
        }
        do {
            n = epoll_wait(pool->epollfd, evs, EPOLL_EVENTS_MAX, -1);
            for(int i=0;i<n;i++) {
                ev = evs + i;
                struct EpollStub *stub = (struct EpollStub *)ev->data.ptr;
                if(stub->type!=EREAD_STAP) {
                    #ifdef __MDEBUG
                    printf("EREAD: Wrong event: %d\n",stub->type);
                    #endif
                    continue;
                }
                else {
    //            inf = (struct StpInfo*)ev->data.ptr;
                    inf = (struct StpInfo*)stub->pointer;
                    fd = inf->fd;
                    #ifdef __MDEBUG
                    printf("EREAD fd: %d\n",fd);
                    #endif
///do something here
                    } 
    ....

Тема 2: Прослушивание клиентских сокетов

    struct epoll_event ev;
    pool->epollfd = epoll_create1(0);
    if (pool->epollfd == -1) {
       return -1;
    }
    ev.events = EPOLLIN;
    for(int i=0;i<pool->sockets.count;i++) {
        struct EpollStub *stub = &pool->sockets.stub[i];
        stub->type = EACCEPT_CONN;
        stub->pointer = pool->sockets.fd[i];
        ev.data.ptr = stub;
        if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, (int)stub->pointer, &ev) = -1) {
             return -1;
       }
    }
...

    cfd = epoll_wait(pool->epollfd, &ev, 1, -1);
    if(is_working(pool,cfd)) {
        struct EpollStub *stub = (struct EpollStub *)ev.data.ptr;
        if(stub->type!=EACCEPT_CONN) {
            #ifdef __MDEBUG
            printf("EACCEPT: Wrong event: %d\n",stub->type);
            #endif
        }
        else {
            #ifdef __MDEBUG
            printf("EACCEPT fd: %d\n",(int)stub->pointer);
            #endif
            break;
///do something here
        }
    }
    ....

ядро: opensuse-3.1.0-1.2-desktop
Они получают события друг от друга. Я сделал EpollStub просто чтобы быть уверенным, что они получают. Без этого первое событие возвращает указатель, второй дескриптор, и в результате возникает ошибка сегментации при получении дескриптора и использовании его в качестве указателя.
Я не думаю, что это нормальное поведение. Это ошибка в ядре или где я не прав?

1 Ответ

1 голос
/ 15 декабря 2011

Это ошибка в вашем коде.Вы перепутали pool->epollfd с epollfd в нескольких местах, например:

    epollfd = epoll_create1(0);
    if (epollfd == -1) {
            return -1;
    }
    ev->events = EPOLLIN;
    for(int i=0;i<plugins->count;i++) {
         inf = &plugins->stp[i];
         stub[i].type = EREAD_STAP;
         stub[i].pointer = inf;
         ev->data.ptr = stub+i;
         if (epoll_ctl(pool->epollfd, EPOLL_CTL_ADD, inf->fd, ev) == -1) {
             close(epollfd);
             return -1;
         }
    }
    do {
        n = epoll_wait(pool->epollfd, evs, EPOLL_EVENTS_MAX, -1);

Вы создаете epollfd, но затем изменяете pool->epollfd и ждете этого.Если у вас есть два разных набора событий, вам нужно использовать два разных epoll fd.

Механизм epoll полностью независим от потоков.Он не привязывает события или наборы к потокам.Любой поток может добавить или удалить дескриптор в или из набора.Любой поток может получать события для любого набора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...