2015-03-17 3 views
3

Я работаю над многопоточным кодом сервера, где я создаю 2 потока, которые взаимодействуют с блокирующим TCP Socket после accept().Использование select() then read() против цикла blocking read()

Тема № 1 проверяет, есть ли команды из очереди сообщений и записывается в сокет. Тема № 2 - это простой цикл while, который вызывает read, а затем блокирует, если нет готовых к чтению данных.

Однако мой коллега сказал мне, что я не должен делать то время цикла с read, как он будет тратить циклы CPU (Это блокирует read, не ядро ​​положить нить спать?), Что я должен использовать select() системы затем запустите сокет.

Я ошибаюсь, считая прочитанную нить? Какой подход лучше?

+2

Что использовали os? Конечно - вы можете использовать select/poll/epoll. Например: http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_61/rzab6/poll.htm – Deep

+0

Это чистая программа для Linux, точнее SLES11. – hastartes

ответ

2

Вы правы, что поток не потребляет процессор во время блокировки на I/O.

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

Что касается того, чтобы предпочесть блокировки на read() или блокированием select() (или poll()) для управления одним каналом, это немного из сравнения яблок к апельсинам, но если таковые есть выбор, то это более простой в блок на read(). Это то, что я сделал бы. Сравнение яблок и яблок будет больше по линиям нескольких потоков или дочерних процессов, каждый из которых блокирует read(), используя другой канал, против одного потока одного процесса, управляющего несколькими каналами, с помощью select().

+0

Не было бы проще читать() также быстрее по сравнению с выполнением двух системных вызовов с помощью select(), а затем читать? – hastartes

+0

@hastartes, чуть быстрее, да, но вы вряд ли заметите разницу. Производительность в подобной ситуации обязательно связана с фактической передачей данных. –

-3

Цикл вокруг, чтобы увидеть, есть ли данные, это не лучший способ сделать это, как предложил ваш друг. Это отнимает процессорное время. Этот метод называется опросом, что является неэффективным способом этого.

Вместо этого Чтение должно вестись по событию. Это означает, что поток Read не будет запущен вообще, пока не будут доступны данные для чтения. Итак, что ваш друг предложил правильно. Вы должны перейти к модели, управляемой событиями. То, что вызвал так называемый вызов Select(), указывает, что стек TCP информирует прочитанный поток, когда есть данные.

поэтому вместо того, чтобы ваш поток проверял, доступны ли данные непрерывно, TCP сообщит вам, когда будут данные для вас.

Надежда его ясно

+1

Цикл чтения не потребляет CPU при блокировке ввода-вывода. Опрос отбрасывает процессор, но никакой опрос не выполняется программой, описанной OP; это будет то, что вы получаете с * неблокирующими * чтениями. –

+0

Не 'select()' также форма опроса? –

+1

@ PaŭloEbermann, no select() не является формой опроса, по крайней мере, не в эти дни. В конце 80-х и начале 1990-х годов некоторые Unixes реализовали select() как цикл опроса, потому что у них не было правильной базовой архитектуры драйверов для поддержки надлежащего механизма блокировки.Реализация select() на Cygwin также опроса (он устанавливает поток для каждого дескриптора файла, каждый из которых имеет доступ к данным, доступным) или, по крайней мере, для этого. – bazza

Смежные вопросы