Я пишу довольно простой сервер в 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 секунд между каждым циклом?
Я новичок в написании сетевого кода, поэтому я уверен, что я просто делаю что-то глупое. Любой совет будет очень благодарен!
Правильный способ - использовать выбор или опрос. – Max
Используйте 'select' и * do not * создайте поток для каждого входящего соединения - вместо этого, когда приходит соединение, нажмите что-нибудь в (потокобезопасную) очередь и создайте небольшой пул потоков, каждый из которых захватывает элемент из очереди, обрабатывает и повторяет. –