Я пишу довольно простой сервер на С++.
Я получил архитектуру, подобную этой:
Один поток (сервер) постоянно зацикливается на accept(), ожидая подключения (docs).
Каждое обнаруженное соединение создает поток, который зацикливается на recv() ожидании чтения и send(), который отправляет что-либо из своей очереди (получить документы), (отправить документы).
Тем не менее, я хочу иметь возможность (из внешнего потока) сообщить серверу или отдельным соединениям, чтобы они по существу убили себя. Проблема в том, что accept() и recv() оба блокируются до тех пор, пока не обнаружат какую-либо активность, поэтому у них нет возможности проверить, установлен ли их элемент should_kill_self или что-то в этом роде. Поэтому, чтобы исправить это, я назвал fcntl(sock_fd, F_SETFL, O_NONBLOCK) файловых дескрипторов, чтобы они этого не делали.
Таким образом, у меня есть сервер, постоянно перебирающий accept() и проверяющий should_kill_self, и у меня есть каждое соединение, перебирающее recv(), проверяющее, есть ли что-нибудь в очереди к send(), и проверяющее should_kill_self.
Таким образом, я могу подать им сигнал убить себя в любое время, но побочный эффект, который я заметил, заключается в том, что они берут на себя огромные объемы обработки. Мне интересно, делаю ли я с этой настройкой что-то глупое, что приводит к избыточным вычислениям. Мне ВООБЩЕ не нужно, чтобы это был сервер со сверхнизкой задержкой, так что «правильный» способ облегчить это, например, спать в течение 10 секунд между каждым циклом?
Я новичок в написании сетевого кода, поэтому я почти уверен, что просто делаю что-то глупое. Любой совет будет принят с благодарностью!
selectи не создавайте поток для каждого входящего соединения. из которых захватывает элемент из очереди, обрабатывает и повторяет. - person Jerry Coffin   schedule 31.10.2014