정책¶
이벤트 루프 정책은 이벤트 루프의 관리를 제어하는 프로세스별 전역 객체입니다. 각 이벤트 루프는 기본 정책이 있는데, 정책 API를 사용하여 변경하고 사용자 정의할 수 있습니다.
정책은 컨텍스트의 개념을 정의하고 컨텍스트마다 별도의 이벤트 루프를 관리합니다. 기본 정책은 컨텍스트를 현재 스레드로 정의합니다.
사용자 정의 이벤트 루프 정책을 사용하여, get_event_loop()
, set_event_loop()
및 new_event_loop()
함수의 동작을 사용자 정의할 수 있습니다.
정책 객체는 AbstractEventLoopPolicy
추상 베이스 클래스에 정의된 API를 구현해야 합니다.
정책을 얻고 설정하기¶
다음 함수는 현재 프로세스의 정책을 가져오고 설정하는 데 사용할 수 있습니다:
-
asyncio.
get_event_loop_policy
()¶ 현재의 프로세스 전반의 정책을 돌려줍니다.
-
asyncio.
set_event_loop_policy
(policy)¶ 현재 프로세스 전반의 정책을 policy로 설정합니다.
policy를
None
으로 설정하면, 기본 정책이 복원됩니다.
정책 객체¶
추상 이벤트 루프 정책 베이스 클래스는 다음과 같이 정의됩니다:
-
class
asyncio.
AbstractEventLoopPolicy
¶ asyncio 정책의 추상 베이스 클래스.
-
get_event_loop
()¶ 현재 컨텍스트의 이벤트 루프를 가져옵니다.
AbstractEventLoop
인터페이스를 구현하는 이벤트 루프 객체를 반환합니다.이 메서드는 절대
None
을 반환해서는 안 됩니다.버전 3.6에서 변경.
-
set_event_loop
(loop)¶ 현재 컨텍스트에 대한 이벤트 루프를 loop로 설정합니다.
-
new_event_loop
()¶ 새 이벤트 루프 객체를 만들고 반환합니다.
이 메서드는 절대
None
을 반환해서는 안 됩니다.
-
get_child_watcher
()¶ 자식 프로세스 감시자 객체를 얻습니다.
AbstractChildWatcher
인터페이스를 구현하고 있는 감시자 객체를 돌려줍니다.이 함수는 유닉스 전용입니다.
-
set_child_watcher
(watcher)¶ 현재의 자식 프로세스 감시자를 watcher로 설정합니다.
이 함수는 유닉스 전용입니다.
-
asyncio에는 다음과 같은 내장 정책이 제공됩니다:
-
class
asyncio.
DefaultEventLoopPolicy
¶ 기본 asyncio 정책. 유닉스와 윈도우 플랫폼 모두에서
SelectorEventLoop
를 사용합니다.수동으로 기본 정책을 설치할 필요는 없습니다. asyncio는 기본 정책을 자동으로 사용하도록 구성됩니다.
-
class
asyncio.
WindowsProactorEventLoopPolicy
¶ ProactorEventLoop
이벤트 루프 구현을 사용하는 대안 이벤트 루프 정책.가용성: 윈도우.
프로세스 감시자¶
프로세스 감시자는 이벤트 루프가 유닉스에서 자식 프로세스를 관찰하는 방법을 사용자 정의할 수 있도록 합니다. 특히, 이벤트 루프는 자식 프로세스가 언제 종료했는지 알 필요가 있습니다.
asyncio에서, 자식 프로세스는 create_subprocess_exec()
와 loop.subprocess_exec()
함수로 만들어집니다.
asyncio는 자식 관찰자가 구현해야 하는 AbstractChildWatcher
추상 베이스 클래스를 정의하며, SafeChildWatcher
(기본적으로 사용하도록 구성됩니다)와 FastChildWatcher
의 두 가지 구현이 있습니다.
서브 프로세스와 스레드 절도 참조하십시오.
다음 두 함수를 사용하여 asyncio 이벤트 루프에서 사용되는 자식 프로세스 감시자 구현을 사용자 정의할 수 있습니다:
-
asyncio.
get_child_watcher
()¶ 현재 정책에 대한 현재 자식 감시자를 반환합니다.
-
asyncio.
set_child_watcher
(watcher)¶ 현재 정책에 대한 현재 자식 관찰자를 watcher로 설정합니다. watcher는
AbstractChildWatcher
베이스 클래스에 정의된 메서드를 구현해야 합니다.
참고
제삼자 이벤트 루프 구현은 사용자 정의 자식 관찰자를 지원하지 않을 수 있습니다. 이러한 이벤트 루프에서는, set_child_watcher()
사용은 금지되거나 효과가 없습니다.
-
class
asyncio.
AbstractChildWatcher
¶ -
add_child_handler
(pid, callback, *args)¶ 새로운 자식 처리기를 등록합니다.
PID가 pid 인 프로세스가 종료할 때
callback(pid, returncode, *args)
가 호출되도록 배치합니다. 같은 프로세스에 대해 다른 콜백을 지정하면 이전 처리기가 교체됩니다.callback 콜러블은 스레드 안전해야 합니다.
-
remove_child_handler
(pid)¶ PID가 pid 인 프로세스의 처리기를 제거합니다.
이 함수는 처리기가 성공적으로 제거되면
True
를, 제거할 것이 없으면False
를 반환합니다.
-
attach_loop
(loop)¶ 감시자를 이벤트 루프에 연결합니다.
감시자가 이전에 이벤트 루프에 연결되었으면, 새 루프에 연결하기 전에 먼저 제거됩니다.
참고: loop는
None
일 수 있습니다.
-
close
()¶ 감시자를 닫습니다.
이 메서드는 하부 자원을 정리하기 위해 호출해야 합니다.
-
-
class
asyncio.
SafeChildWatcher
¶ 이 구현은
SIGCHLD
시그널에 대해 명시적으로 모든 프로세스를 폴링하여 프로세스를 스포닝하는 다른 코드를 방해하지 않습니다.이것은 안전한 해법이지만 많은 수의 프로세스를 처리할 때 상당한 오버헤드가 있습니다 (
SIGCHLD
가 수신될 때마다 O(n)).asyncio는 기본적으로 이 안전한 구현을 사용합니다.
-
class
asyncio.
FastChildWatcher
¶ 이 구현은
os.waitpid(-1)
를 직접 호출하여 종료된 모든 프로세스를 거둡니다. 프로세스를 스포닝하는 다른 코드를 망가뜨리고 그들의 종료를 기다릴 수 있습니다.많은 수의 자식을 처리할 때 눈에 띄는 오버헤드가 없습니다 (자식이 종료될 때마다 O(1)).
사용자 정의 정책¶
새로운 이벤트 루프 정책을 구현하려면, DefaultEventLoopPolicy
의 서브 클래스를 만들고 사용자 정의 동작이 필요한 메서드를 재정의하는 것이 좋습니다, 예를 들어:
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
def get_event_loop(self):
"""Get the event loop.
This may be None or an instance of EventLoop.
"""
loop = super().get_event_loop()
# Do something with loop ...
return loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())