您好我有一些問題包裝Python類中的一些ZMQ拉客戶端。這些類被實例化並通過多處理模塊在子進程中調用。當客戶端功能全部有效時,但是當它們是類時,poller.poll()會掛起。ZMQ輪詢不在類實例中工作
代碼波紋管有兩個版本:一個可以工作,另一個不可以。爲什麼?
import zmq
import time
import sys
import random
from multiprocessing import Process
def server_push(port="5556"):
context = zmq.Context()
socket = context.socket(zmq.PUSH)
socket.bind("tcp://*:%s" % port)
print "Running server on port: ", port
# serves only 5 request and dies
for reqnum in range(10):
if reqnum < 6:
socket.send("Continue")
else:
socket.send("Exit")
break
time.sleep (1)
def server_pub(port="5558"):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)
publisher_id = random.randrange(0,9999)
print "Running server on port: ", port
# serves only 5 request and dies
for reqnum in range(10):
# Wait for next request from client
topic = random.randrange(8,10)
messagedata = "server#%s" % publisher_id
print "%s %s" % (topic, messagedata)
socket.send("%d %s" % (topic, messagedata))
time.sleep(1)
class Client:
def __init__(self,port_push, port_sub):
context = zmq.Context()
self.socket_pull = context.socket(zmq.PULL)
self.socket_pull.connect ("tcp://localhost:%s" % port_push)
print "Connected to server with port %s" % port_push
self.socket_sub = context.socket(zmq.SUB)
self.socket_sub.connect ("tcp://localhost:%s" % port_sub)
self.socket_sub.setsockopt(zmq.SUBSCRIBE, "9")
print "Connected to publisher with port %s" % port_sub
# Initialize poll set
def __call__(self):
poller = zmq.Poller()
poller.register(self.socket_pull, zmq.POLLIN)
poller.register(self.socket_sub, zmq.POLLIN)
# Work on requests from both server and publisher
should_continue = True
print "listening"
while should_continue:
print "hello"
socks = dict(poller.poll())
print poller
if self.socket_pull in socks and socks[self.socket_pull] == zmq.POLLIN:
message = self.socket_pull.recv()
print "Recieved control command: %s" % message
if message == "Exit":
print "Recieved exit command, client will stop recieving messages"
should_continue = False
if self.socket_sub in socks and socks[self.socket_sub] == zmq.POLLIN:
string = self.socket_sub.recv()
topic, messagedata = string.split()
print "Processing ... ", topic, messagedata
def client(port_push, port_sub):
context = zmq.Context()
socket_pull = context.socket(zmq.PULL)
socket_pull.connect ("tcp://localhost:%s" % port_push)
print "Connected to server with port %s" % port_push
socket_sub = context.socket(zmq.SUB)
socket_sub.connect ("tcp://localhost:%s" % port_sub)
socket_sub.setsockopt(zmq.SUBSCRIBE, "9")
print "Connected to publisher with port %s" % port_sub
# Initialize poll set
poller = zmq.Poller()
poller.register(socket_pull, zmq.POLLIN)
poller.register(socket_sub, zmq.POLLIN)
# Work on requests from both server and publisher
should_continue = True
while should_continue:
socks = dict(poller.poll())
if socket_pull in socks and socks[socket_pull] == zmq.POLLIN:
message = socket_pull.recv()
print "Recieved control command: %s" % message
if message == "Exit":
print "Recieved exit command, client will stop recieving messages"
should_continue = False
if socket_sub in socks and socks[socket_sub] == zmq.POLLIN:
string = socket_sub.recv()
topic, messagedata = string.split()
print "Processing ... ", topic, messagedata
if __name__ == "__main__":
# Now we can run a few servers
server_push_port = "5556"
server_pub_port = "5558"
Process(target=server_push, args=(server_push_port,)).start()
Process(target=server_pub, args=(server_pub_port,)).start()
#~ Process(target=client,args=(server_push_port,server_pub_port)).start()
Process(target=Client(server_push_port,server_pub_port)).start()
在與子模塊有限的工作我已經注意到,它可以難以診斷異常情況 - 你確定你已經正確診斷並且你沒有在其他地方發現異常嗎?我過去做過的一件事是明確地將子進程分解爲我可以在自己的控制檯窗口中監視的進程。 – 2012-03-19 13:26:05
這只是一個測試代碼,沒有什麼隱藏的。無論是假想中斷,發生在pyzmq內。我希望有一個解決方法,以便不必等待pyzmq中的修復。 我同意使用多進程時很難調試,但它提供的便利超過了這個問題。 – fccoelho 2012-03-19 13:41:09