select() внутри бесконечного цикла использует значительно больше процессора на виртуальной машине RHEL 4.8, чем на машине Solaris 10.

StackOverflow https://stackoverflow.com/questions/2435449

Вопрос

У меня есть приложение-демон, написанное на C, и в настоящее время оно работает без каких-либо известных проблем на компьютере с Solaris 10.Я сейчас портирую его на Linux.Мне пришлось внести минимальные изменения.Во время тестирования он проходит все тестовые случаи.Никаких проблем с его функциональностью нет.Однако, когда я просматриваю использование ЦП в режиме ожидания на моем компьютере с Solaris, он использует около 0,03% ЦП.На виртуальной машине под управлением Red Hat Enterprise Linux 4.8 этот же процесс использует весь доступный процессор (обычно где-то в диапазоне 90%+).

Моей первой мыслью было, что что-то не так с циклом событий.Цикл событий представляет собой бесконечный цикл (while(1)) с вызовом select().Timeval настроен так, что timeval.tv_sec = 0 и timeval.tv_usec = 1000.Это кажется достаточно разумным для того, что делает процесс.В качестве теста я наткнулся на timeval.tv_sec до 1.Даже после этого я увидел ту же проблему.

Есть ли что-то, что мне не хватает в том, как select работает в Linux и в Linux?Юникс?Или это работает по-другому с ОС, работающей на виртуальной машине?Или, может быть, есть что-то еще, чего мне совершенно не хватает?

Еще одна вещь: я не уверен, какая версия сервера VMware используется.Хотя он был обновлен около месяца назад.

Это было полезно?

Решение

Я считаю, что Linux возвращает оставшееся время, записывая его в параметр времени вызова select(), а Solaris этого не делает.Это означает, что программист, не знакомый со спецификацией POSIX, может не сбросить параметр времени между вызовами select.

Это приведет к тому, что первый вызов будет иметь тайм-аут 1000 мкс, а все остальные вызовы будут иметь тайм-аут 0 мсек.

Другие советы

Как сказал Зан Линкс, timeval изменяется при выборе в Linux, поэтому вам следует переназначать правильное значение перед каждым вызовом выбора.Также я предлагаю проверить, находится ли какой-либо файловый дескриптор в определенном состоянии (например,конец файла, одноранговое соединение закрыто...).Возможно, при портировании обнаруживается какая-то скрытая ошибка при анализе возвращаемых значений (FD_ISSET и т. д.).Это случилось и со мной несколько лет назад в порту цикла, управляемого выбором:Я неправильно использовал возвращаемое значение, и в rd_set был добавлен закрытый fd, что привело к сбою выбора.На старой платформе использовался неправильный fd со значением выше maxfd, поэтому он игнорировался.Из-за той же ошибки программа не распознала ошибку выбора (select() == -1) и зациклилась навсегда.

Пока!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top