2016-12-19 22 views
6

historii:Konieczność zamknięcia asyncio pętli zdarzeń explicite

Jestem obecnie patrząc przez asyncio basic examples, w szczególności this one - najprostszy możliwy klient HTTP. Główną funkcją uruchamia pętlę zdarzeń, biegnie aż do pobierania danych jest kompletna i zamyka pętlę zdarzeń:

def main(): 
    loop = get_event_loop() 
    try: 
     body = loop.run_until_complete(fetch()) 
    finally: 
     loop.close() 
    print(body.decode('latin-1'), end='') 

Ale kod działa również jeśli pominąć loop.close():

def main(): 
    loop = get_event_loop() 
    body = loop.run_until_complete(fetch()) 
    print(body.decode('latin-1'), end='') 

Pytanie :

Podczas gdy istnieje przykład, pytanie jest ogólne - co może potencjalnie pójść źle, jeśli zapomni się zamknąć pętlę zdarzeń asyncio? Czy pętla zdarzeń będzie zawsze niejawnie zamknięta?

+1

Będziesz przeciekać zasoby. –

+0

Jak myślisz, co to jest domyślne zamknięcie? Wydaje mi się, że odśmiecanie pamięci, na którym można polegać tylko po zakończeniu programu, jak długo program będzie działał po zakończeniu pętli zdarzeń, dopóki program się nie skończy? –

+0

@FilipHaglund dzięki. Czy możesz wymyślić sposób na sprawdzenie/wykazanie tego? – alecxe

Odpowiedz

3

.close() może być używany przez różne implementacje pętli zdarzeń, aby zwolnić zasoby systemowe przydzielone przez pętlę (lub zrobić cokolwiek innego). Jeśli będziesz przyjrzeć kodeksu _UnixSelectorEventLoop, który jest (domyślnie) IOLoop używany w systemie Linux można znaleźć następujący kod:

def close(self): 
    super().close() 
    for sig in list(self._signal_handlers): 
     self.remove_signal_handler(sig) 

Oto, na przykład, close() usuwa obsługi sygnałów zarejestrowanych z loop.add_signal_handler() .

Ponieważ wiele IOLoops można uruchomić na różnych wątkach lub nowe IOLoops można utworzyć po zamknięciu starego (patrz asyncio.new_event_loop()), zamknięcie ich powinno być uważane za dobry nawyk.

Powiązane problemy