【发布时间】:2016-05-28 22:28:19
【问题描述】:
我想在数据可用时从套接字读取,并且在同一个线程中我想从消息队列中读取项目,如下所示:
while True:
ready = select.select([some_socket, some_messagequeue], [], [])[0]
if some_socket in ready:
read_and_handle_data_from_socket()
if some_messagequeue in ready:
read_and_handle_data_from_messagequeue()
换句话说:一旦线程通过某个进程内部消息传递系统接收到消息,我想中止select()。
根据我现在阅读的内容,我发现了两种方法:selecting 在消息队列本身上或创建一个os.pipe() 以中止select(),但我还没有找到一个好的实现。
方法 1:似乎有两个 Queue 实现:multiprocessing.Queue 和 queue.Queue (Python3)。虽然multiprocessing.Queue 有一个_reader 成员,它可以与select() 一起使用,但queue.Queue 允许任意数据结构排队,而不必弄乱酸洗。
问题:有没有办法在queue.Queue 上也使用select()?
方法 2:如下所示:
import os, queue, select
r, w = os.pipe()
some_socket = 67 # FD to some other socket
q = queue.Queue()
def read_fd():
while True:
ready = select.select([r, some_socket], [], [])[0]
if r in ready:
os.read(r, 100)
print('handle task: ', q.get())
if some_socket in ready:
print('socket has data')
threading.Thread(target=read_fd, daemon=True).start()
while True:
q.put('some task')
os.write(w, b'x')
print('scheduled task')
time.sleep(1)
这是可行的——但在我看来,这段代码非常繁琐,而且不是很pythonic。 问题:有没有更好的方法通过os.pipe(或任何其他实现)发送“信号”?
方法 3..N:问题:您将如何解决这个问题?
我知道 ZeroMQ 之类的库,但由于我正在处理嵌入式项目,我更喜欢原生 Python (3.3) 发行版附带的解决方案。而且我认为应该有一个与第一个示例一样简短的解决方案 - 毕竟我只想中止 select() 如果消息队列上发生某些事情。
【问题讨论】:
标签: python sockets select message-queue