2014-10-31 1 views
0

Я пишу довольно простой сервер в C++.Базовый сервер, занимающий огромные ресурсы ЦП - как облегчить?

Я закончил с архитектурой, подобной этой:

Один поток (сервер) постоянно обхвата над accept() ждут подключения (docs).

Каждое соединение он находит, он запускает поток, который перебирает recv() ждет что-то читать, и send(), который посылает что-либо в своей очереди (recv docs), (send docs).

Тем не менее, я хочу иметь возможность (из внешней нити) сообщать либо серверу, либо отдельным соединениям, чтобы по существу убить себя. Проблема в том, что accept() и recv() блокируют до тех пор, пока не находят какую-либо активность, поэтому нет возможности проверить, установлен ли их член should_kill_self или что-то еще. Поэтому, чтобы исправить это, я назвал fcntl(sock_fd, F_SETFL, O_NONBLOCK) файловыми дескрипторами, чтобы они этого не сделали.

Таким образом, у меня есть сервер постоянно зацикливание над accept() и проверки should_kill_self, и я каждое соединение цикла по recv(), проверьте, если что-нибудь в очереди send() и проверки should_kill_self.

Таким образом, я могу сообщить им, чтобы они убили себя в любое время, но побочный эффект, который я заметил, заключается в том, что они занимаются огромным количеством обработки. Мне интересно, если с этой настройкой я делаю что-то глупое, что приводит к избыточному вычислению. Мне не нужно, чтобы это был сервер с очень низкой задержкой AT ALL, так же как «правильный» способ облегчить это, например, спать в течение 10 секунд между каждым циклом?

Я новичок в написании сетевого кода, поэтому я уверен, что я просто делаю что-то глупое. Любой совет будет очень благодарен!

+1

Правильный способ - использовать выбор или опрос. – Max

+1

Используйте 'select' и * do not * создайте поток для каждого входящего соединения - вместо этого, когда приходит соединение, нажмите что-нибудь в (потокобезопасную) очередь и создайте небольшой пул потоков, каждый из которых захватывает элемент из очереди, обрабатывает и повторяет. –

ответ

1

Возможно, вам необходимо изучить неблокирующие IO в портах завершения Linux или IO на окнах. См. here и here.

Программирование этих потребностей требует дополнительных усилий и затрудняет программирование простого сервера сокетов. Тем не менее, есть библиотеки, которые будут охватывать неблокирующие IO (и IOCP) и предоставляют простой интерфейс для вас. Одним из примеров является ASIO в boost. Существует множество других библиотек даже для Java и других языков.

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