Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从ZMQ拉插座获取数据。如何同步计算?_Python_Sockets_Network Programming_Zeromq_Pyzmq - Fatal编程技术网

Python 从ZMQ拉插座获取数据。如何同步计算?

Python 从ZMQ拉插座获取数据。如何同步计算?,python,sockets,network-programming,zeromq,pyzmq,Python,Sockets,Network Programming,Zeromq,Pyzmq,我让生产商使用拉/推发送数据给多个工人。所有工作人员都需要在执行计算任务之前接收所有数据 我尝试了使用发布/订阅套接字发送“go”的同步,但是由于推送套接字是非阻塞的,所以go在数据流结束之前被接收 发件人: context = zmq.Context() push_socket = self.context.socket(zmq.PUSH) push_socket.bind("tcp://127.0.0.1:5557") pull_socket = self.context.socket(

我让生产商使用拉/推发送数据给多个工人。所有工作人员都需要在执行计算任务之前接收所有数据

我尝试了使用发布/订阅套接字发送“go”的同步,但是由于推送套接字是非阻塞的,所以go在数据流结束之前被接收


发件人:

context = zmq.Context()
push_socket = self.context.socket(zmq.PUSH)
push_socket.bind("tcp://127.0.0.1:5557")

pull_socket = self.context.socket(zmq.PULL)
pull_socket.bind("tcp://127.0.0.1:5558")

for index, data in range(100): 
    push_socket.send_json({"data": data, "id": index})
pub_socket.send_json({"command": "map"})
接收人:

# recieve work
consumer_receiver = context.socket(zmq.PULL)
consumer_receiver.connect("tcp://127.0.0.1:5557")

# receive commands
consumer_command = context.socket(zmq.SUB)
consumer_command.subscribe("")
consumer_command.connect("tcp://127.0.0.1:5559")

poller = zmq.Poller()
poller.register(consumer_receiver, zmq.POLLIN)
poller.register(consumer_command, zmq.POLLIN)

while True:
    events = dict(poller.poll(100))
    if consumer_command in events:
        received = consumer_command.recv_json()
        command = received["command"]
        print("received command : ", command)

    if consumer_receiver in events:
        received = consumer_receiver.recv_json()
        print("received data", received)
接收机输出:

received data {'data': ['Hi'], 'id': 0}
received command :  map   
received data {'data': ['hi'], 'id': 1}
...
我希望:

received data {'data': ['Hi'], 'id': 0}
received data {'data': ['hi'], 'id': 1}
...
received command :  map   

我试图将推送插座的HWM设置为1,但无效


推送完成后,如何向所有工作人员发送同步消息

您对命令和数据使用单独的流-这将始终保证同步问题。在接收方,您将有两个流缓冲区—第一个是要处理大量数据的流缓冲区,第二个是只处理command和poll()的流缓冲区,它们将确保您收到通知,都已准备好读取

我认为有两种方法可以解决这个问题:

1) 保持简单:只使用一个流。你在最后发送的所有内容都将在最后收到。TCP保证这一点。如果您使用的是json,那么只需添加“type”:“command”或“type”:“data”即可区分消息类型


2) 如果出于某种原因,您确实需要两个流(例如,您确实想使用发布者/订阅者模式),则在发送者发送其命令之前,接收方应确认发送者接收到了最后一批数据。如果所有工作人员都需要在使用命令启动任何工作人员之前接收其数据,则也可以选择此选项。

您对命令和数据使用单独的流-这将始终保证同步问题。在接收方,您将有两个流缓冲区—第一个是要处理大量数据的流缓冲区,第二个是只处理command和poll()的流缓冲区,它们将确保您收到通知,都已准备好读取

我认为有两种方法可以解决这个问题:

1) 保持简单:只使用一个流。你在最后发送的所有内容都将在最后收到。TCP保证这一点。如果您使用的是json,那么只需添加“type”:“command”或“type”:“data”即可区分消息类型


2) 如果出于某种原因,您确实需要两个流(例如,您确实想使用发布者/订阅者模式),则在发送者发送其命令之前,接收方应确认发送者接收到了最后一批数据。如果所有工作人员都需要在使用命令启动任何工作人员之前接收其数据,则也可以选择此选项。

您正在寻求实施屏障

ZeroMQ完全是关于参与者模型编程的,一个特点是在发送和接收消息时没有显式的呈现。也就是说,无论另一端是否已读取消息,发送都将返回

因此,这意味着必须在ZeroMQ的参与者模型之上合成屏障(一种渲染类型)

  • 使用推/拉插座对将数据传送给工人
  • 工人使用单独的推/拉插座对向生产商发回“我有数据,准备好继续”信息
  • 让制作人等待这些“我可以继续”的消息
  • 当它从每个工人那里收到一条消息时,在PUB/SUB套接字上向工人发送一条“go”消息 通信顺序流程

    只是出于兴趣,您可能希望将参与者模型编程与通信顺序过程进行比较(在Rust、Erlang和(我认为?)Go中,这是一种回归)。在CSP中,发送/接收消息是一种呈现。这有几个好处

    • 发送方知道已收到消息,而不仅仅是排队
    • 如果一个人有性能和延迟目标,它会迫使他正确地处理体系结构和资源分配。您不能在传输过程中隐藏邮件。因此,如果一个人没有提供足够的工人,那么制作人显然就无法卸载消息;不能通过增加延迟来暂时隐藏缺陷
    • 如果您已经成功地构建了一个可以死锁、活锁等的体系结构,那么它总是会。然而,演员模型的架构在几年内看起来都是完美的,直到有一天网络变得更加繁忙
    要使用CSP实现您想要的功能,您可以省略上面的步骤2和步骤3。当发送给最后一个工人的消息返回时,生产者会知道每个工人都已收到其数据,并且可以立即发送“go”

    就个人而言,我真的希望ZeroMQ可以选择成为CSP,而不是演员。然后它将是神话般的,而不仅仅是非常巨大的。真正好的地方在于,无论是tcp、ipc、inproc等,它们的行为都是一样的(速度变化明显)


    AFAIK Rust、Erlang和Go CSP通道仅限于此过程。ZMQ可以是进程间和/或进程内和/或计算机间的,这使得它非常适合开发可能超过一台计算机的系统。需要将线程卸载到另一台计算机吗?更改连接字符串,无需更改其他代码。非常好。

    您正在寻求实现一个屏障

    ZeroMQ完全是关于参与者模型编程的,一个特点是在发送和接收消息时没有显式的呈现。也就是说,无论另一端是否已读取消息,发送都将返回

    因此,这意味着必须在ZeroMQ的参与者模型之上合成屏障(一种渲染类型)

  • 使用推/拉插座对将数据传送给工人
  • 工人使用单独的推/拉插座对向生产商发回“我有数据,准备好继续”信息
  • 让制作人等待这些“我能亲”