정책¶
이벤트 루프 정책은 이벤트 루프의 관리를 제어하는 프로세스별 전역 객체입니다. 각 이벤트 루프는 기본 정책이 있는데, 정책 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())
