Андрей прав. В неблокирующем режиме VMIN/VTIME не имеют эффекта (FNDELAY/O_NDELAY, похоже, являются вариантами Linux для O_NONBLOCK, портативного флага POSIX).
При использовании select() с файлом в неблокирующем режиме вы получаете событие для каждого байта, который приходит. При высоких скоростях передачи данных это забивает процессор. Лучше использовать режим блокировки с VMIN, так что select() ждет блока данных перед запуском события, а VTIME - для ограничения задержки для блоков, меньших VMIN.
Сэм сказал: «Если вы хотите убедиться, что вы получаете данные каждые полсекунды, вы можете установить vtime» (VTIME = 5).
Интуитивно, вы можете ожидать, что это правда, но это не так. Эта страница BSD termios объясняет это лучше, чем Linux (хотя оба они работают одинаково). Таймер VTIME является таймером . Он начинается с каждого нового байта, поступающего на последовательный порт. В худшем случае select() может подождать до 20 секунд перед запуском события.
Предположим, что у вас есть VMIN = 250, VTIME = 1 и последовательный порт со скоростью 115200 бит/с. Также предположим, что у вас есть подключенное устройство, медленно отправляющее одиночные байты с постоянной скоростью 9 сП. Время между байтами составляет 0,11 секунды, достаточно долго для истечения интервала таймера от 0.10 и выберите(), чтобы сообщить читаемое событие для каждого байта. Все хорошо.
Теперь предположим, что ваше устройство увеличивает скорость вывода до 11 кадров в секунду. Время между байтами составляет 0,09 секунды. Недостаточно времени для истечения таймера между байтами, и каждый новый байт начинается. Чтобы получить читаемое событие, VMIN = 250 должен быть удовлетворен. При 11 сП, что занимает 22,7 секунды. Может показаться, что ваше устройство остановилось, но дизайн VTIME является реальной причиной задержки.
Я тестировал это с помощью двух сценариев, отправителя и получателя Perl, двухпортовой последовательной карты и нуль-модемного кабеля. Я доказал, что это работает, как говорится в справочной странице. VTIME - это таймер интербита, который сбрасывается с появлением каждого нового байта.
Лучшая конструкция имела бы таймер, закрепленный, а не катящийся. Он будет продолжать тикать, пока он не истечет, или VMIN не будет удовлетворен, в зависимости от того, что наступит раньше. Существующий проект может быть исправлен, но есть 30 лет наследия для преодоления.
На практике вы можете столкнуться с таким сценарием редко. Но он скрывается, так что будьте осторожны.
В статье http://www.cmrr.umn.edu/~strupp/serial.html#config говорится: «Тайм-ауты игнорируются в режиме канонического ввода или когда параметр NDELAY установлен в файл через открытый или fcntl ", а затем он говорит:" VTIME указывает количество времени ожидания входящих символов в десятых долях секунды. Если VTIME установлен в 0 (по умолчанию), чтение будет блокировать (ждать) неопределенно, если параметр NDELAY не установлен порт с открытым или fcntl ». Это означает, что когда VTIME равно 0, вы должны использовать 'O_NDELAY', но когда VTIME> 0, то вы не должны использовать' O_NDELAY'. Это правильно? – CMCDragonkai