【问题标题】:select() on socket and another event mechanism套接字上的 select() 和另一种事件机制
【发布时间】: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.Queuequeue.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


    【解决方案1】:

    您可以创建一个pipe 对文件描述符,通过写入它的写入端发出队列推送信​​号,并在管道的读取端等待同一select 中的队列活动。

    特别是在 Linux 上,还有eventfd(2) 系统调用可以用于相同目的。 而不是pipe(2)(可能是this有用)。

    【讨论】:

    • 嗯,这正是我在“方法 2”中所做的——我错过了什么吗?
    • 啊,是的,没有仔细阅读问题。将修改。
    【解决方案2】:

    方法 3: 有两个线程。 1 等待选择。 2 等待消息队列。互斥以防止它们同时触发。如果您不打算使用线程,为什么还要使用它们?

    【讨论】:

    • 嗯,我需要消息队列与第一个线程通信。我必须从第一个线程访问一些资源,第二个线程指示第一个线程做事。所以我真的需要一种方法让第一个线程从消息队列中读取。
    猜你喜欢
    • 1970-01-01
    • 2017-01-17
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    相关资源
    最近更新 更多