почему select () постоянно возвращает 0 иногда - PullRequest
2 голосов
/ 12 марта 2019

У меня проблема с select () на платформе arm linux, с одной стороны это arm linux как tcp клиент, с другой стороны - pc как tcp сервер. Клиент tcp подключился к серверу и получает данные с сервера в течение фиксированного интервала времени, например, 5 мс. В большинстве случаев селектор работает нормально, но иногда случаются странные вещи: функция select () непрерывно возвращает ноль (тайм-аут), после этого селектор возвращает нормальный, но размер прочитанных данных ненормальный, как следует из фотографии.

Кто-нибудь знает, что причина? Большое спасибо.

enter image description here enter image description here

    while(scan->is_child_thread_active)
    {
        FD_ZERO(&read_fd);
        w_time.tv_sec = 0; 
        w_time.tv_usec = (100*1000);//100ms
        if (scan->tcp_socket_fd > 0)
        {
            FD_SET(scan->tcp_socket_fd, &read_fd);
        }
        else
        {
            break;
        }
        mxfd = scan->tcp_socket_fd;
        if ((n_ready=select(mxfd + 1, &read_fd, (fd_set *) NULL, (fd_set *) NULL, &w_time)) < 0 )
        {
            print_err("select error: %s \n", strerror(errno));
            close(scan->tcp_socket_fd);
            scan->tcp_socket_fd = -1;
            continue;
        }
        if (0x00 == n_ready ) 
        {
            print_err("select timeout \n");
            continue;
        }
        scan->handleSocketRead(scan, read_fd, scan->tcp_socket_fd);
    }

кодирование ручки для чтения следующим образом

if (sock_fd > 0 && FD_ISSET(sock_fd, &read_fd_set)) 
{
    if ((n_read = recv(sock_fd, scan->tcp_buffer_, TCP_BUF_SZ, 0))<=0) 
    {
        print_err("read tcp error,fd= %d:%s\n", sock_fd, strerror(errno));
        close(sock_fd);
        sock_fd = -1;
        return;
    }
    curr_data_time_ = get_ms_time_pf();
    RBT_MS_T delta_time = curr_data_time_ - last_data_time_;
    printf("rcv data len %d , delta time = %llu\n", n_read, delta_time);
    scan->writeBufferBack(scan->tcp_buffer_, n_read);
    while( scan->handleNextPacket() ) {}
    last_data_time_ = get_ms_time_pf();


}

Кстати, плата под управлением в ядре arm freescale imx6q. И самое длинное замерзшее длится более 1 секунды на следующей фотографии, и другие журналы показывают, что время иногда длится 5 секунд или даже больше.

Что-то не так в конфигурации Linux?

Ответы [ 2 ]

3 голосов
/ 12 марта 2019

За Документация POSIX select() :

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

После успешного завершения pselect() и select() функции должны возвращать общее количество битов, установленных в битовых масках.В противном случае должно быть возвращено -1, и должно быть установлено значение errno, указывающее на ошибку.

Ноль является вполне допустимым результатом, означающим, что в дескрипторе (файлах) файла не было обнаружено никаких действий.

Сетевой трафик не гарантируется бесперебойно.Если это проблема для вашего использования, вам нужно обратиться к сети, так как с кодом нет проблем.

0 голосов
/ 12 марта 2019

Linux не является ОС реального времени.Это означает, что, хотя его многозадачность, как правило, гладкая, и каждая задача выполняется так, как будто она имеет полную систему для себя, могут возникать разногласия.В этом случае некоторые процессы могут быть заморожены на небольшой промежуток времени.

Когда я читаю ваш вывод, самый длинный замороженный случай длится всего 1231 мс, чуть больше одной секунды.Это довольно долго для компьютера, но может произойти в зависимости от других задач, скорости диска и сети, температуры (здесь не совсем шутка ...) и т. Д.

Вторая длится 15 мс, что можетбыть вызвано одной медленной операцией ввода-вывода.

Если вы не используете ОСРВ, вы должны быть готовы сделать такие вещи.

...