Разрешены ли несколько мультидескрипторов cURL в одном цикле событий?

Я создаю сервер, который будет обрабатывать несколько одновременных клиентских подключений (около 100), где клиенты загружают множество данных и серверных пакетов и отправляют их в другое удаленное место.

Что я хотел бы сделать, так это «группировать» данные, отправленные от каждого клиента, в свои собственные структуры данных (скажем, в какой-то связанный список) и обрабатывать эти списки одновременно. Пропускная способность важна, поэтому я хотел бы иметь возможность одновременно отправлять как можно больше данных (скажем, до 10 000 простых дескрипторов, обрабатываемых одновременно).

Подходы, о которых я думаю, следующие:

  1. Имейте большой пул потоков (скажем, 100 потоков), где каждый процесс легко обрабатывается.
  2. Иметь один поток, обрабатывающий несколько дескрипторов для всех 10 000 простых дескрипторов.
  3. Создайте несколько потоков (скажем, 4), обрабатывающих несколько дескрипторов, чтобы каждый обрабатывал 2500 простых дескрипторов.
  4. Имейте несколько дескрипторов для каждого клиента, поэтому потенциально 100 потоков, каждый из которых обрабатывает несколько дескрипторов.

Я хотел бы знать, могу ли я «объединить» № 2 и № 3, чтобы у меня был один поток, который обрабатывает несколько множественных дескрипторов в одном цикле событий. Разрешено ли такое, и если да, то есть ли в этом смысл? Если это возможно, это удовлетворило бы мое требование группировки клиентской обработки по нескольким дескрипторам, а также позволило бы мне использовать постоянные соединения для каждого мультидескриптора. Если нет, то единственным способом в полной мере воспользоваться преимуществами постоянных подключений для всех клиентов будет вариант №4. Предпочтительно, я хотел бы уменьшить количество используемых потоков из-за определенных ограничений модели программирования, которой мы следуем.


person James    schedule 04.09.2014    source источник


Ответы (1)


Это настолько сложный вопрос, что коротко ответить на него невозможно. Это также будет зависеть от множества местных условий и других требований, которые могут у вас быть, но здесь не указаны. Я бы посоветовал вам построить несколько прототипов и сравнить их друг с другом для ваших конкретных условий.

Да: вы можете использовать несколько мультидескрипторов в одном потоке, но это, вероятно, будет немного причудливо, и я не думаю, что вы увидите какие-либо преимущества от этого, а не просто используя один и добавляя все легко справляется с этим единственным.

Моим личным предпочтением было бы № 3, но, возможно, используйте немного больше потоков, чем 4, просто потому, что сегодня у вас легко есть процессоры с 8 потоками, а скоро их будет 16, и для случаев, когда вы привязаны к процессору, вам лучше распределить загрузите как можно больше для максимальной производительности (но не слишком много, чтобы по-прежнему получать выгоду от кешей и повторного использования соединения и т. д.).

Кроме того, поскольку каждый мультидескриптор затем обрабатывает N простых дескрипторов, всегда существует риск того, что вам придется что-то делать для специальной передачи, которая заставит другие передачи N-1 немного приостановиться, и тогда лучше, если вы разделить общее количество на несколько потоков, чтобы затем не блокировать все передачи.

Наконец, чтобы ускорить процесс, вы можете использовать API на основе событий curl_multi_socket_action. для максимальной производительности.

person Daniel Stenberg    schedule 05.09.2014
comment
Большое спасибо за ваш быстрый ответ! Если выбрать вариант № 3, я планировал иметь столько потоков на ядра, так что полностью с вами согласен. Я также планировал использовать curl_multi_socket_action API, так что, похоже, я был на правильном пути (я впервые использую curl). По-прежнему хорошо знать, что разрешено иметь несколько мультирук в потоке, но я думаю, что выберу вариант № 3 и посмотрю, как это пойдет. - person James; 08.09.2014