我在我的程序中使用python 2.7和zerorpc以及线程。当我在一个Thread对象中通过zerorpc调用一个远程函数时,出现了异常“LoopExit:此操作将永远阻塞”。
我的代码示例:
class Reminder(Thread):
def __init__(self):
super(Reminder, self).__init__()
self.rpc_client = zerorpc.Client('tcp://10.10.10.3:10001')
def run(self):
while True:
try:
self.rpc_client.alarm_by_wx('alive', 'zhanghe') # the exception arise here
except Exception, e:
logger.exception('rpc error')
time.sleep(24*60*60)
if __name__ == '__main__':
r = Reminder()
r.start()
r.join()
异常:
Traceback (most recent call last):
File "api_monitor.py", line 92, in run
self.rpc_client.alarm_by_wx('alive', 'zhanghe')
File "/usr/local/lib/python2.7/dist-packages/zerorpc/core.py", line 257, in <lambda>
return lambda *args, **kargs: self(method, *args, **kargs)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/core.py", line 246, in __call__
bufchan.emit_event(request_event)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/channel.py", line 235, in emit_event
self._channel.emit_event(event)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/heartbeat.py", line 116, in emit_event
self._channel.emit_event(event, timeout)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/channel.py", line 155, in emit_event
self._multiplexer.emit_event(event, timeout)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/channel.py", line 67, in emit_event
return self._events.emit_event(event, timeout)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/events.py", line 328, in emit_event
self._send(parts, timeout)
File "/usr/local/lib/python2.7/dist-packages/zerorpc/events.py", line 125, in __call__
self._send_queue.put(parts, timeout=timeout)
File "/usr/local/lib/python2.7/dist-packages/gevent/queue.py", line 447, in put
result = waiter.get()
File "/usr/local/lib/python2.7/dist-packages/gevent/hub.py", line 575, in get
return self.hub.switch()
File "/usr/local/lib/python2.7/dist-packages/gevent/hub.py", line 338, in switch
return greenlet.switch(self)
LoopExit: This operation would block forever
如果我在主线程中像下面的代码一样调用rpc函数,它会毫无例外地运行。
if __name__ == '__main__':
rpc_client = zerorpc.Client('tcp://10.10.10.3:10001')
while True:
try:
rpc_client.alarm_by_wx('alive', 'zhanghe') # the exception arise here
except Exception, e:
logger.exception('rpc error')
time.sleep(24*60*60)
出了什么问题? zerorpc可以在多线程环境中工作吗?谢谢你的任何想法。
答案 0 :(得分:0)
由于zerorpc使用了gevent库,因此无法从用于建立与服务器的原始连接的其他线程中调用客户端方法。
您可以通过如下修改代码来使其工作:
class Reminder(Thread):
def __init__(self):
super(Reminder, self).__init__()
def run(self):
self.rpc_client = zerorpc.Client('tcp://10.10.10.3:10001')
while True:
try:
self.rpc_client.alarm_by_wx('alive', 'zhanghe') # no exception should arise here
except Exception, e:
logger.exception('rpc error')
time.sleep(24*60*60)
if __name__ == '__main__':
r = Reminder()
r.start()
r.join()