низкий уровень использования процессора для мониторинга подключения к локальному хосту - PullRequest
0 голосов
/ 04 апреля 2019

Кажется, что неблокирующее соединение с localhost всегда сразу завершается неудачно, тогда poll () немедленно возвращается с флагом POLLIN, установленным в процентах. Это не позволяет ЦП войти в состояние блокировки, и вся система работает с довольно высокой загрузкой процессора.

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1470 panruoc+  20   0   12956   1956   1820 S  26.2  0.0   2:09.49 zz1

Любое предложение ценится. Вот мой код тестирования

int main(int argc, char *argv[])
{
    struct sockdesc {
        char *host;
        int port;
        int sockfd;
    };
    struct sockdesc sdes[] = {
        {"localhost", 6000},
        {"111.206.239.212", 6000},
    };
    unsigned int i;

    for(i = 0; i < 2; i++) {
        tcp_connect(sdes[i].host, sdes[i].port, &sdes[i].sockfd);
        printf("sockfd = %d, %d\n", sdes[i].sockfd, errno);
    }

    if(!nonblocking)
        return 0;

    struct pollfd pollfds[2];
    pollfds[0].fd = sdes[0].sockfd;
    pollfds[1].fd = sdes[1].sockfd;
    pollfds[0].events = POLLIN;
    pollfds[1].events = POLLIN;

    int conns;
    for(conns = 0; conns != 3; ) {
        int nfds = poll(pollfds, 2, -1);
        if(nfds <= 0)
            exit(1);
        for(i = 0; (int)i < nfds; i++) {
            if(pollfds[i].revents) {
                if(pollfds[i].revents & POLLIN)
                    conns |= i;
                printf(" fd = %d, revents = 0x%04x\n", sdes[i].sockfd, pollfds[i].revents);
            }
        }
    }
    return 0;
}

БР, Руочень

1 Ответ

0 голосов
/ 04 апреля 2019

Ваш цикл for выглядит подозрительно:

for(conns = 0; conns != 3; ) {

Когда conns когда-либо становится тремя?

Похоже, ваше намерение здесь:

            if(pollfds[i].revents & POLLIN)
                conns |= i;

Но если i равно 0 для первого сокета, conns |= i не изменит значения.

И когда на обоих сокетах будут доступны данные, ваш вызов poll начнет немедленно возвращаться, но вызастряли в бесконечном цикле.Следовательно, высокая загрузка процессора.

Похоже, что ваш код предназначен для того, чтобы оставаться в цикле до тех пор, пока оба сокета не будут иметь данные, доступные для чтения.Затем вырваться из цикла.Поэтому я подозреваю, что вы действительно имели в виду следующее:

                conns |= (i+1);

Есть и другие проблемы.poll возвращает количество допустимых дескрипторов сокета.Следовательно, эта строка;

for(i = 0; (int)i < nfds; i++) {

Так что, если сокет, связанный с pollfds [1], имеет доступные данные, nfds будет только 1. Следовательно, ваш цикл будет оценивать только, если pollfds[0] имеет данные.

Давайте очистим ваш код:

int ready_set = 0x00;
int all_ready_set = 0x03;
int num_sockets = 2;
while (ready_set != all_ready_set)
{
    int nfds = poll(pollfds, 2, -1);

    if(nfds <= 0)
    {
        // I would not actually exit. If a socket gets closed locally, you would have a valid and expected error, but maybe that can't happen in your program
        exit(1);
    }

    for (i = 0; i < num_sockets; i++)
    {
        if (pollfds[i].revents & POLLIN)
        {
            int mask = 0x01 << i;
            pollfds[i].events = 0; // stop listening for events on this socket
            ready_set |= mask;
        }
    }
}
...