Вопрос

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

Теперь у меня есть следующие вопросы:

  1. Если я использую поток (Qt), куда мне поместить системный вызов select для мониторинга последовательного порта?
  2. Безопасен ли поток системного вызова select?
  3. Это интенсивно использует процессор, потому что в моем приложении происходит много вещей, включая обновление графического интерфейса?

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

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

Решение

А Спецификация POSIX (выбрать) это место для поиска select определение.Я лично рекомендую poll - он имеет лучший интерфейс и может обрабатывать любое количество дескрипторов, а не ограничение, определяемое системой.

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

С использованием select/poll с тайм-аутом «ожидание» остается на стороне ядра, что означает, что поток обычно переводится в спящий режим.Пока поток спит, он не использует процессорное время.Цикл while/for select с другой стороны, вызов без тайм-аута приведет к более высокой загрузке процессора, поскольку вы постоянно вращаетесь в цикле.

Надеюсь это поможет.

РЕДАКТИРОВАТЬ:Также, select/poll может иметь непредсказуемые результаты при работе с такой же дескриптор в нескольких потоках.Простая причина этого в том, что первый поток может быть разбужен, поскольку дескриптор готов к чтению, а второму потоку придется ждать завершения операции. следующий "доступно для чтения" пробуждение.

Пока ты не selectиспользуя один и тот же дескриптор в нескольких потоках, у вас не должно возникнуть проблем.

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

Это системный вызов — я думаю, он должен быть потокобезопасным.

Раньше я этого не делал, но был бы весьма удивлён, если бы это было не так.Насколько интенсивен процессор select() на мой взгляд, во многом зависит от количества дескрипторов файлов, которые вы ожидаете. select() в основном используется для ожидания готовности нескольких (>1) дескрипторов файлов.

Следует также упомянуть, что select() не следует использовать для опроса дескрипторов файлов — из соображений производительности.Обычное использование:Вы закончили свою работу, и может пройти некоторое время, прежде чем произойдет следующее.Теперь вы приостанавливаете свой процесс с помощью select и позволяете запустить другой процесс. select() обычно приостанавливает активный процесс.Как это работает вместе с потоками, я не уверен!Я бы подумал, что весь процесс (и все потоки) приостановлены.Но это может быть задокументировано.Это также может зависеть (в Linux), используете ли вы системные потоки или пользовательские потоки.Ядро не будет знать пользовательские потоки и, следовательно, приостановит весь процесс.

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