Сервер сокетов с epoll и потоками
Я пытаюсь создать сервер сокетов в C для совместного редактора в реальном времени http://en.wikipedia.org/wiki/Collaborative_real-time_editor но я не знаю, что является лучшей архитектурой сервера для него.
сначала я пытался использовать select для сервера сокетов, но после этого я читал об epoll, и теперь я думаю, что epoll-лучший выбор, потому что клиент отправит каждое письмо, которое пользователь напишет на textarea, на сервер, поэтому у сервера будет много данных для обработки.
кроме того, я хочу использовать потоки с epoll, но я точно не знаю, как их использовать. Я хочу использовать потоки, потому что я думаю, что лучше использовать 2 или все процессоры на целевой машине.
мой план
создать 2 потока при запуске сервера
первый поток проанализирует новых клиентов и подготовит их к чтению или отправке
в второй поток будет иметь задание для чтения и отправки данных из / клиентам
проблема в том, что эти 2 потока будут использовать while(1) с epoll_wait.
мои вопросы: это хорошая архитектура сервера для использования epoll с потоками? Если нет, то какие у меня есть варианты ?
EDIT: я не могу использовать libevent или libev или другие библиотеки, потому что это проект колледжа, и я не могу использовать внешняя библиотека.
3 ответов
я думаю, вы пытаетесь перепроектировать эту проблему. The epoll
архитектура в Linux была предназначена для ситуаций, когда у вас есть тысячи параллельных соединений. В таких случаях накладные расходы, кстати,poll
и select
системные вызовы определены, будут основным узким местом на сервере. Решение использовать poll
или select
и epoll
зависит от количества подключений, а не количество данных.
для того, что вы делаете, кажется, как хотя люди в вашей системе редактирования сойдет с ума после того, как вы нажмете несколько десятков параллельных редакторов. Используя epoll
вероятно, заставит вас сойти с ума; они играют несколько трюков с API, чтобы выжать дополнительную производительность, и вы должны быть очень осторожны, обрабатывая информацию, которую вы получите обратно от звонков.
этот вид приложения звучит так, как будто он будет связан с сетью ввода-вывода вместо привязки к процессору. Я бы попытался написать его как однопоточный сервер с poll
первый. Когда вы получаете новый текст, буферизуйте его для своих клиентов, если это необходимо, а затем отправьте его, когда сокет принимает write
звонки. Используйте неблокирующий ввод-вывод; единственный вызов, который вы хотите заблокировать, - это poll
звонок.
если вы делаете значительный объем обработки данных после их получения, но перед отправкой их обратно клиентам, то вы можете извлечь выгоду из многопоточности. Сначала напишите однопоточную версию, а затем, если вы привязаны к процессору (проверьте с помощью top
) и большинство время процессора тратится в функциях, где вы занимаетесь обработкой данных (проверьте с помощью gprof
), добавьте многопоточность для обработки данных.
если вы хотите, вы можете использовать каналы или сокеты Unix-домена внутри программы для связи между различными потоками - - - таким образом все в основном потоке можно управлять событиями и обрабатывать через poll
. Кроме того, с помощью этой модели вы можете даже использовать несколько процессов с fork
вместо различные потоки.
возможно, вы захотите использовать что-то вроде libev или libevent вместо написания собственной реализации обработки событий. они дают вам кросс-платформенный обработчик событий, который будет использовать все, что подходит (будь то select
, poll
, epoll
, kqueue
или что-нибудь еще) и, скорее всего, на более низких накладных расходах, чем наличие двух потоков, передающих работу друг другу.