Select () системный вызов в темах? - PullRequest
6 голосов
/ 26 июня 2009

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

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

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

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

Ответы [ 2 ]

7 голосов
/ 26 июня 2009

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

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

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

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

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

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

0 голосов
/ 26 июня 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...