Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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 来自单个线程的ZeroMQ进程间通信丢失消息_Python_Unit Testing_Zeromq_Pyzmq - Fatal编程技术网

Python 来自单个线程的ZeroMQ进程间通信丢失消息

Python 来自单个线程的ZeroMQ进程间通信丢失消息,python,unit-testing,zeromq,pyzmq,Python,Unit Testing,Zeromq,Pyzmq,我目前正在探索测试zeromq应用程序的可能性。我的印象是,我可以在同一个线程中有一个发布者/订阅者,让发布者发布和订阅者订阅,而不会丢失消息。然而,当我让发布者发送几条消息时,没有一条消息能够传递给订阅者 以下是我使用的代码: import zmq def main(): ctx = zmq.Context.instance() sender = ctx.socket(zmq.PUB) sender.setsockopt(zmq.HWM, 1000) send

我目前正在探索测试zeromq应用程序的可能性。我的印象是,我可以在同一个线程中有一个发布者/订阅者,让发布者发布和订阅者订阅,而不会丢失消息。然而,当我让发布者发送几条消息时,没有一条消息能够传递给订阅者

以下是我使用的代码:

import zmq

def main():
    ctx = zmq.Context.instance()
    sender = ctx.socket(zmq.PUB)
    sender.setsockopt(zmq.HWM, 1000)
    sender.bind('tcp://*:10001')

    rcvr = ctx.socket(zmq.SUB)
    rcvr.setsockopt(zmq.HWM, 1000)
    rcvr.connect('tcp://127.0.0.1:10001')
    rcvr.setsockopt(zmq.SUBSCRIBE, "")

    for i in range(100):
        sender.send('%i' % i)

    while True:
        try:
            print rcvr.recv(zmq.NOBLOCK)
        except zmq.ZMQError:
            break


if __name__ == '__main__':
    main()
当运行这个时,我没有得到任何输出


让我印象深刻的是,接收方在发送方发送之前就已经连接好了,因此应该对这些消息进行排队。或者这是一个完全错误的假设,我应该使用推/拉方式来代替吗?

您应该将子插座连接到端口10000而不是10001。当前,子套接字正在等待发布者,而发布套接字正在等待订阅者。0mq允许“客户端”连接而不存在“服务器”的功能也意味着连接到端口10001时不会引发错误,这是设计上的

让我印象深刻的是,在发送方发送之前,接收器已经连接好了

事实并非如此——接收方已经开始了连接过程,但这并不意味着连接过程已经完成。连接是异步的

如果您实际将其用于进程内通信,我建议您使用
inproc
传输,这不是问题:

url = 'inproc://whatever'
sender.bind(url)
...
recvr.connect(url)

我认为这是一个慢连接问题的例子,如中所述

这种“慢加入者”的症状经常影响到足够多的人,我们将对此进行详细解释

我认为主要的问题是,在订户套接字开始侦听之前,所有消息都已发送,消息飞过并被丢弃。在设置套接字和发送消息之间设置延迟不起作用,因为在接收器开始侦听之前,最后一条消息已经发送

正如您所建议的,推/拉套接字在内存中执行队列作业。您可以像这样在单个进程中在套接字之间发送作业

# pushpull.py
import zmq

def main():
    ctx = zmq.Context()
    sender = ctx.socket(zmq.PUSH)
    sender.bind('tcp://*:10001')

    rcvr = ctx.socket(zmq.PULL)
    rcvr.connect('tcp://127.0.0.1:10001')

    for i in range(100):
        sender.send_unicode('%i' % i)

    while True:
        msg = rcvr.recv()
        print(msg)

if __name__ == '__main__':
    main()
或者,如果您想使用发布/订阅套接字,则在套接字设置和消息发送之间需要两个进程和一个
time.sleep(1)

首先启动接收器

# rcvr.py
import zmq

def main():
    ctx = zmq.Context()
    rcvr = ctx.socket(zmq.SUB)
    rcvr.connect('tcp://127.0.0.1:10001')
    rcvr.setsockopt_string(zmq.SUBSCRIBE, "")

    while True:
        msg = rcvr.recv()
        print(msg)

if __name__ == '__main__':
    main()
然后发送者

# sender.py
import zmq
import time

def main():
    ctx = zmq.Context()
    sender = ctx.socket(zmq.PUB)
    sender.bind('tcp://*:10001')

    time.sleep(1)
    for i in range(100):
        sender.send_unicode('%i' % i)

if __name__ == "__main__":
    main()
接收:

b'0'
b'1'
b'2'
b'3' ...
目前,我正在使用Python3.3和Pyzmq13.1.0以及awesome发行版,因此zmq调用中的一些字符串处理以及打印函数略有不同。
希望有帮助。

很好地发现了它!然而,这是一个打字错误,并不能解决问题(但是,没有理由不使用TCP,是吗?其他原因是我所说的,非inproc连接是异步的,因此您在实际连接对等方之前就开始发送,因此消息会被删除。如果您在发送之前睡了一觉,它会工作得很好。检查并搜索慢速连接程序。