PyZMQ 是否为每个新的客户端连接创建线程? [英] Does PyZMQ handle creating threads for each new client connection?

查看:18
本文介绍了PyZMQ 是否为每个新的客户端连接创建线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 PyZMQ 创建请求/回复服务器,并且我试图弄清楚为每个新客户端连接创建线程的行为是否由 PyZMQ 自动处理.最终,我试图弄清楚来自一个客户端的需要很长时间才能回复的请求是否会阻止来自所有其他客户端的请求.

I'm using PyZMQ to create a request/reply server, and I'm trying to figure out if the act of creating a thread for each new client connection is handled by PyZMQ automatically. Ultimately, I'm trying to figure out if a request from one client that takes a long time to reply to will block requests from all other clients.

通常,我会在 Python 套接字实例上调用 accept ,阻塞直到建立新连接,并在单独的线程中处理任何新连接.但是,PyZMQ 套接字似乎不支持这样的工作流程.那么,这在 PyZMQ 中是如何处理的呢?如果 PyZMQ REP 套接字有多个客户端连接到它,它如何正确地将回复路由回发出请求的客户端?而且,我如何设计我的代码,以便在客户端发出长时间运行的请求时不会阻止来自其他客户端的请求?

Normally, I would call accept on a Python socket instance, block until a new connection is made, and handle any new connections in separate threads. However, PyZMQ sockets do not seem to support such a workflow. So, how is this handled in PyZMQ? If a PyZMQ REP socket has multiple clients connected to it, how does it go about correctly routing replies back to the clients that made the requests? And, how can I go about designing my code such that requests from other clients aren't blocked when a client makes a long-running request?

我知道我可以使用 PyZMQ 提供的基于 Tornado 的 EventLoop,我只是想更好地了解如果它不是一个选项,它将如何工作.

I know I could use the Tornado-based EventLoop provided with PyZMQ, I'm just trying to better understand how it would work if that weren't an option.

推荐答案

ZeroMQ 暴露为类固醇套接字",但还有另一种实现通信的方法.

ZeroMQ exposed as "sockets on steroids", but there is another approach for implementing a communciation.

首先,忘记连接传统套接字中的对等点的电线.在 0mq 中,您有一个量子传送器",它将您的消息从一段代码传送到另一段代码,从而对您隐藏实际的传送工作.您不能只询问 0mq 有多少客户端连接到套接字,或者您是否有客户端.因此,ZeroMQ 不能用作套接字的直接替代品.

First of all, forget about wire that links peers in traditional sockets. In 0mq, you have a "quantum teleporter", which delivers your messages from one piece of code to another, hiding actual delivery work from you. You can't just ask 0mq how many clients are connected to the socket or if you have clients at all. ZeroMQ cannot be used as a drop-in replacement for sockets because of that.

相反,0mq 会给你一顶魔术师帽子,你可以从中取出一些白兔.想象一下,那顶帽子的底部与巨大的管道网络相连,另一边有多个奇妙的工厂.这些工厂有时会给你的帽子寄一些东西,当你从帽子里拿出来时,你会发现自己手里拿着一只兔子,或者一束鲜花或其他东西.除非在那件事上有明确的标签(即多部分消息的一部分指向消息的来源),否则您无法确定该事物是从哪个工厂发送的.

Instead, 0mq gives you a magician hat you take some white rabbits from. Imagine that bottom of that hat connected with a gigantic network of pipes with multiple factories of wonderful things on the other side. These factories sometimes send some stuff to your hat, and when you get from the hat you can find yourself with a rabbit in your hands, or bouquet of flowers or something other. You cannot determine from what factory that thing had been sent unless there was an explicit sticker on that thing (i.e. one part of multipart message points to origin of the message).

从帽子里取出兔子后,您可能想要发送一些东西,并且 0mq 对不同的套接字类型会有不同的表现.对于 REP 套接字,它将直接向消息源发送答案,因为 DEALER 将在连接的对等方之间循环响应,而 ROUTER 在接收消息时为您提供有关对等方的确切内部地址的大量知识,并允许您在发送消息时设置明确的目的地.

After you take the rabbit from the hat, you may want to send something back, and 0mq will behave differently for different socket types. For REP sockets, it will send answer directly to origin of message, for DEALER will round robin answers across connected peers, and ROUTER gives you immense knowledge of exact internal address of peer when receiving message and allows you to set explicit destination while sending message.

总而言之,如果您想为每个通信客户端使用单独的线程,您需要以下内容:

To sum it up, if you want a separate thread for each communicating client you need the following things:

  • 客户应明确表明自己的身份.
  • 在服务器上,您运行一个线程(调度程序)来接收消息、从中获取客户端身份并选择一个线程进行处理.
  • 调度程序将此消息发送到线程(或产生一个线程)并继续为传入的消息流提供服务.
  • 线程接收消息,对其进行处理并通过调度程序(如果需要)将响应发送给客户端.
  • 调度程序将答复路由到客户端.

这是一种在记住经典套接字知识的情况下实现在 zeromq 上的多客户端套接字服务器"的方法.

This is a way to implement "multi-client socket server on zeromq" with classic socket knowledge in mind.

但这不是解决问题的 0mq 方法.

But it is not a 0mq approach for the problem.

在 0mq 中,您可以将处理逻辑放在一个线程中(上面示例中的调度程序)并将其实现为循环 receive request ->过程 ->发送答案 ->接收....当处理时间不是问题时非常适合.但是当它是时,0mq 风格的解决方案涉及客户端和工作人员(执行实际工作)之间的任务队列代理.然后,broker 逻辑比上面提到的接收-应答循环稍微复杂一点,而且工作线程的实现方式相同.查看 zguide 中的示例 - A Request-Reply Message Broker

In 0mq you can just put your processing logic in one thread (dispatcher from the example above) and implement it as a loop receive request -> process -> send answer -> receive .... Fits perfectly when processing time is not a question. But when it is, 0mq-style solution involves task-queue broker between clients and workers (which perform actual work). And then, broker logic is a little more complicated than a receive-answer loop mentioned above, and the worker is implemented in the same way. See examples in zguide - A Request-Reply Message Broker

这篇关于PyZMQ 是否为每个新的客户端连接创建线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆