Многопоточный TCP слушатель с epoll и EPOLLET в C

Я хочу написать многопоточный TCP-слушатель, используя epoll и EPOLLET,

Я видел, что есть несколько возможностей:

  1. Каждый поток имеет свой собственный epoll fd, делает bind() с помощью SO_REUSEPORT (но только до ядра Linux 3.9) и обрабатывает свои собственные соединения. EPOLLONESHOT в этом случае не понадобится, поскольку каждый поток обрабатывает свои собственные файловые дескрипторы.

  2. Существует основной поток, который принимает соединения, и несколько рабочих потоков, которые обрабатывают эти соединения. Каждый рабочий поток имеет свой собственный epoll fd. Как основной поток в этом случае может справедливо распределить соединения между рабочими потоками? Он может добавить файловый дескриптор к epoll fd другого потока с использованием метода циклического перебора (но может случиться, что этот конкретный поток все еще занят обработкой другого соединения). Или соединения могут быть добавлены в глобальную очередь, и основной поток будет использовать pthread_cond_signal(), но тогда нам нужен мьютекс и условная переменная.

  3. Существует основной поток, который принимает соединения, и несколько рабочих потоков, которые обрабатывают эти соединения. Существует глобальный epoll fd, EPOLLONESHOT тогда потребуется в этом случае, поэтому не все потоки просыпаются для одного и того же события.

Я знаю, что если EPOLLET используется, как только я получаю уведомление о событии, я должен истощить fd, пока не получу EAGAIN,

Если опция сокета SO_REUSEPORT не поддерживается (старое ядро), какой вариант будет лучшим?

2 ответа

Решение
  1. Решение без использования SO_REUSEPORT будет иметь общий epoll fd и общий прослушиватель, которые являются общими для всех потоков. EPOLLONESHOT требуется, поэтому только один поток обрабатывает события для определенного fd одновременно.
  1. Вариант 1. но без SO_REUSEPORT - иметь общий сокет прослушивания. Каждый рабочий поток запускает свой собственный цикл обработки событий, и в дополнение к обработке своих собственных соединений они также выполняют неблокирующую функцию accept() в сокете прослушивания. Более подробное описание см., Например, http://aosabook.org/en/nginx.html
Другие вопросы по тегам