控制asyncio协程的调度优先级可能吗?

时间:2018-01-20 21:18:19

标签: python-asyncio

有没有办法控制所有准备运行的协同程序中的调度优先级?

具体来说,我有几个协同程序处理来自网络的流I / O到几个队列,第二组协同程序将数据从队列中摄取到数据结构中。这些摄取协同程序指示第三组协程,每当新数据被摄取时,它们都会分析该数据结构。

来自网络的数据到达是具有非确定性消息速率的无限流。我希望分析步骤在新数据到达时立即运行,但不要在处理所有待处理数据之前运行。我看到的问题是,根据调度的顺序,分析协程可以在读者协程之前运行,也可以准备好数据,因此分析协程甚至无法检查摄取队列中的待处理数据,因为它可能尚未被读取即使这些读者协同程序已准备好运行,网络还没有。

一种解决方案可能是将协同程序组织成优先级组,以便在分析协同程序之前始终安排读取程序协同程序,如果它们都能够运行,但我没有看到这样做的方法。

是否有asyncio的功能可以实现此优先级?或者我可能会问错误的问题,我可以重新设计协程,这样就不会发生这种情况(但我没有看到)。

- 编辑 -

基本上我有一个N协程,看起来像这样:

while True:
  data = await socket.get()
  ingestData(data)
  self.event.notify()

所以我遇到的问题是,我无法知道任何其他N-1套接字在执行此协程时已准备好数据,因此我无法知道是否应通知该事件。如果我可以在分析协程(等待self.event.wait())之上优先处理这些协同程序,那么我可以确定在安排分析协程时它们都不可运行。

1 个答案:

答案 0 :(得分:1)

asyncio并不支持显式指定协同程序优先级,但使用库提供的工具实现相同的效果是很简单的。给出你问题中的例子:

async def process_pending():
    while True:
    data = await socket.get()
        ingestData(data)
        self.event.notify()

您可以使用asyncio.wait直接等待套接字,然后您就会知道哪些套接字是可操作的,并且只有在处理完所有套接字后才会通知分析器。例如:

def _read_task(self, socket):
    loop = asyncio.get_event_loop()
    task = loop.create_task(socket.get())
    task.__process_socket = socket
    return task

async def process_pending_all(self):
    tasks = {self._read_task(socket) for socket in self.sockets}
    while True:
        done, not_done = await asyncio.wait(
            tasks, return_when=asyncio.FIRST_COMPLETED)
        for task in done:
            ingestData(task.result())
            not_done.add(self._read_task(task.__process_socket))
        tasks = not_done
        self.event.notify()