Многопоточная публикация с помощью zmqC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Многопоточная публикация с помощью zmq

Сообщение Anonymous »

У меня вопрос, как лучше всего публиковать сообщения из многих тем для одного подписчика в ZMQ. У меня есть веб-сервер, написанный на C++, который для каждого соединения должен отправлять подписчику сообщение ZMQ. Эти серверы могут иметь от сотен до тысяч одновременных подключений, поэтому мне любопытно, какой самый эффективный способ написать этому подписчику. Я могу придумать три разных способа.

Поделиться соединением

Я не верю, что этот способ сработает, но в основном имеет один указатель соединения и передает его всем потокам. Я предполагаю (не смог найти много информации, когда искал на сайте ZMQ), это вызовет состояние гонки, поскольку я не думаю, что zmq_msg_send() является потокобезопасным. Чтобы решить эту проблему, я мог бы поместить мьютекс вокруг отправки, но меня беспокоит скорость, поскольку мой сервер должен работать как можно быстрее.

Общая очередь

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

Соединение для каждого потока

Единственный способ избежать ожидания мьютекса - это открыть соединение zmq для каждого потока (то есть для каждого соединения). Вхожу, как процесс по одному пользовательскому соединению на поток). Возможно, это выполнимо, хотя я не знаю, как работает zmq_connect. Это блокируется до тех пор, пока соединение не будет установлено? В идеале мой поток выглядел бы примерно так:

Код: Выделить всё

user_connection()
{
createZMQConnection();
doWork();
sendData();
}
Однако, если создание соединения блокируется, возможно, лучше использовать общую очередь.

Кто-нибудь создавал подобное приложение или кто-нибудь знает, какой будет рекомендуемый шаблон? Будем очень признательны за любую информацию.

Редактировать:

Спасибо за ответ, я просто изучил документацию zmq и нашел многое из того, о чем вы говорили, но, возможно, вы можете немного уточнить.

Что касается моей инфраструктуры, у меня есть много пабов и один подписчик. Пабы соединяются, а сабвуферы являются обязательными.

У меня есть несколько блоков с балансировкой нагрузки, в каждом из которых выполняется несколько потоков. В целом я вижу около 30 000 сообщений в секунду. На один ящик я, вероятно, увижу около 2000–4000 сообщений в секунду. Мое обычное время обработки запроса составляет около 40 мс, поэтому у меня часто открыто около 100-200 одновременных экземпляров. Я не был уверен, будет ли проблемой открытие 200 одновременных объектов сокетов или это будет способ работы ZMQ. Судя по всему, я должен передавать zmq::context в каждый поток и создавать там сокеты.

Я примерно так представляю, как будет работать код, дайте мне знать, если это выглядит правильно

Код: Выделить всё

void receiveConnection()
{
zmq::context_t context(1);
doWorkClass c(context);
c.run();
}

doWorkClass(context)
{
socket(context, ZMQ_PUB);
}

void doWorkClass::run()
{
sendString = doWork();
s_send(socket,sendString);
}
Поэтому я использую один контекст для всех сокетов и создаю один сокет для каждого потока, выполняю свою работу и отправляю свое сообщение.

Подробнее здесь: https://stackoverflow.com/questions/261 ... h-with-zmq
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»