Сервер сокетов с 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 или что-нибудь еще) и, скорее всего, на более низких накладных расходах, чем наличие двух потоков, передающих работу друг другу.


просто начать использовать libevent или libev и следовать их примеру. Есть многочисленные примеры-не пытайтесь изобрести здесь что-то новое