Я начал использовать ZeroMQ для IPC и сделал простой echo-client/server, и я удивлен одной штукой. Вот код C++ (с использованием zmq.hpp
и zmq_addon.hpp
).Как ZeroMQ REQ/REP обрабатывает несколько клиентов?
Сервер:
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REP);
socket.bind("ipc:///tmp/machine-1");
while (1) {
zmq::multipart_t m;
m.recv(socket);
int i = m.poptyp<int>();
i++;
m.addtyp<int>(i);
m.send(socket);
}
Клиент:
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.connect("ipc:///tmp/machine-1");
int i = 0;
while (1) {
int save = i;
zmq::multipart_t m;
m.addtyp<int>(i);
m.send(socket);
m.recv(socket);
i = m.poptyp<int>();
if (i != (save + 1))
break;
if ((i % 100000) == 0)
std::cerr << "i : " << i<< "\n";
}
я работает, как ожидалось. Клиент отправляет int
, сервер делает плюс один и отправляет его обратно.
Теперь волшебство я не понимаю: я понял, что я могу запускать клиент несколько раз параллельно, и он продолжает работать, для каждого клиента правильно.
Проверка save+1
на i
всегда в порядке.
Как ZMQ обрабатывает проблему параллелизма на стороне сервера? Как он узнает, к какому клиенту следует отправить ответ?
Существует этот вопрос на SO, но это не ответ на мой вопрос: ZeroMQ REQ/REP on ipc:// and concurrency
Я только читаю руководство, вы правы в документации 'zmq_connect', это хорошо описано. Ключ в том, что для ZMQ_REQ/ZMQ_RES-соединения также требуется определенный recv/send-pattern. Таким образом, они могут заблокировать доступ к сокету при вызове recv и освободить его при вызове send (наоборот, для другой стороны) –