如何检查asyncio循环是否有任何关联的套接字

时间:2017-03-07 11:10:41

标签: python-3.x python-asyncio

asyncio.Task.all_tasks()给出了一个事件循环的所有任务的列表,但我找不到任何类似的套接字,特别是与循环相关的数据报套接字?

没有插座和然后,任务可以表示循环的“生命结束”。

问题是,在以下示例中,当loop_not_empty()放入False时,当任务集为空并且时没有相关的套接字(即两秒后)

示例:

import asyncio
import socket
import threading

class Handler(asyncio.Protocol):
    def connection_made(self, transport):
        self.transport = transport
        print("connection made")

    def datagram_received(self, data, addr):
        if data == b'die':
            print("shutting down")
            self.transport.abort()

@asyncio.coroutine
def sometask():
    yield from asyncio.sleep(1)
    print("task done")

def loop_not_empty(l):
    # if asyncio.Task.all_tasks() == set() and WHAT_GOES_HERE
    #   return False
    return True

def main():
    a,b = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)

    l = asyncio.get_event_loop()

    asyncio.ensure_future(sometask(), loop=l)
    asyncio.ensure_future(l.create_datagram_endpoint(Handler, sock=a), loop=l)

    threading.Timer(2, lambda: b.send(b'die')).start()

    while loop_not_empty(l):
        l.run_until_complete(asyncio.sleep(1, loop=l))

main()

1 个答案:

答案 0 :(得分:0)

这是一个使用简单类和asyncio.Event()来计算活动作业数量的解决方案,并在完成所有作业后发出循环信号:

import asyncio

import random


class UseCounter:
    def __init__(self, loop=None):
        self.loop = loop
        self.event = asyncio.Event(loop=loop)
        self.n = 0  # The number of active jobs

    def __enter__(self):
        self.enter()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.exit()

    def enter(self):
        self.n += 1

    def exit(self):
        self.n -= 1
        if self.n == 0:
            self.event.set()

    async def wait(self):
        return await self.event.wait()


async def my_coroutine(counter, term):
    with counter:
        print("start", term)
        n = random.uniform(0.2, 1.5)
        await asyncio.sleep(n)
        print("end", term)


loop = asyncio.get_event_loop()
counter = UseCounter(loop)
terms = ["apple", "banana", "melon"]
for term in terms:
    asyncio.ensure_future(my_coroutine(counter, term))

loop.run_until_complete(counter.wait())

loop.close()

对于上面的示例,请将.enter()添加到connection_made(),将.exit()添加到connection_lost()