我希望在数据可用时从套接字读取,并且在同一个线程中我想从消息队列中读取项目,如下所示:
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()
。
从我现在读到的内容中我发现了两种方法:select
在消息队列本身上,或创建os.pipe()
以便中止select()
,但我找不到一个好的方法实施。
方法1 :似乎有两个Queue
实现:multiprocessing.Queue
和queue.Queue
(Python3)。虽然multiprocessing.Queue
有一个_reader
成员可以与select()
一起使用,但只有queue.Queue
允许任意数据结构排队,而不必捣乱。
问题:还有办法在select()
上使用queue.Queue
吗?
方法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()
如果消息队列上发生了某些事情。
答案 0 :(得分:0)
方法3:有两个主题。 1等待选择。 2等待消息队列。 Mutex防止它们同时发射。如果您不打算使用它们,为什么要有线程?
答案 1 :(得分:0)
您可以创建 pipe
对文件描述符,通过写入其写入端来发送信号队列,并在读取端的同一select
中等待队列活动。管道。
在Linux上,还有还 eventfd(2)
系统调用,可以将用于同一目的。而不是pipe(2)
({ {3}}我可能会有用。)