2017-03-07 13 views
0

asyncio.Task.all_tasks()給出了一個事件循環的所有任務的列表,但我找不到任何類似的套接字,特別是與數據報關聯的套接字一個循環?如何檢查asyncio循環是否有任何關聯的套接字

沒有插座&任務然後可以表示循環的「生命結束」。

的問題是,在下面的例子中,要放什麼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() 
+0

這個不清楚。請提供一段代碼,您希望執行此「生命週期」檢查。 – Udi

+0

試圖澄清一個例子。 – ttyridal

回答

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()

+0

有趣。這基本上是重新計數事件循環。它確實解決了這個問題,但是「侵入性」是因爲所有的任務和套接字都需要記住做參考舞。我會把它打開幾天,希望有一個更好的解決方案。 – ttyridal

相關問題