我正在运行一个线程,该线程从队列中获取消息,将其发送到客户端,并接收确认。如果客户端断开连接,则线程捕获套接字错误并终止。问题是如果msgQ为空,则线程永远不会检查套接字连接。有没有办法设置此代码,所以即使队列为空,检查套接字? (问题是,没有消息,没有什么可以发送)
我是否需要发送一个特殊的ping?pong!消息如果msgQ为空(并在客户端检查消息是日志数据还是ping?)?任何帮助,将不胜感激。
def run(self):
while not self._terminate:
try:
msgs = self.msgQ.get()
self.sock.send(pickle.dumps(msgs))
rdy = pickle.loads(self.sock.recv(2097152))
except socket.error, EOFError:
print 'log socketmanager closing'
self.terminate()
break
except Empty: pass
答案 0 :(得分:1)
如果msgQ
为空,则对self.msgQ.get()
的调用会引发Empty
例外,并完全跳过对self.sock.send()
和self.sock.recv()
的调用。 Empty
例外的异常处理程序不执行任何操作,因此您的代码将busy wait,直到msgQ
显示某些内容而没有调用send
或recv
。
一种可能的解决方案是使用python select module检查异常处理程序中的套接字。这些方面的东西:
def run(self):
while not self._terminate:
try:
msgs = self.msgQ.get()
self.sock.send(pickle.dumps(msgs))
rdy = pickle.loads(self.sock.recv(2097152))
except socket.error, EOFError:
print 'log socketmanager closing'
self.terminate()
break
except Empty:
results = select.select([], [], [self.sock], 0.5) # timeout of 0.5 seconds
if self.sock in results[2]:
print 'exceptional condition on socket'
self.terminate()
break
答案 1 :(得分:0)
如果您使用的是Queue.Queue
,则可以使用可选的block
和timeout
args致电Queue.get()
,或致电Queue.get_nowait()
,其等效于{{1}如果队列为空,将立即返回:
Queue.get(block=False)
答案 2 :(得分:0)
我有一个将Queue和Pipe包装到类中的想法。然后使用select模块检查套接字和管道,不会使用轮询来监视事件。
以下用于包装队列和管道的示例代码:
class MyQueue(object):
"""docstring for MyQueue"""
def __init__(self, arg):
super(MyQueue, self).__init__()
# self.arg = arg
self._queue = Queue.Queue()
self._rdfd, self._wrfd = os.pipe()
return
def enQ(self, item=None, block=True, timeout=None):
os.write(self._wrfd, '+')
self._queue.put(item)
return
def deQ(self, block=True, timeout=None):
_itm = self._queue.get(block=block, timeout=timeout)
_msg = os.read(self._rdfd, 1)
return _itm
def get_notify(self):
return self._rdfd
print 'append queue'
self.inp.append(self._myq.get_notify())
print 'append socket'
self.inp.append(self.sock)
print self.inp
_slp = self.slp
_inp = self.inp
_out = self.out
_err = self.err
_in, _out, _err = select.select(_inp, _out, _err, _slp)