# 이벤트 루프

머리말

이벤트 루프는 모든 asyncio 응용 프로그램의 핵심입니다. 이벤트 루프는 비동기 태스크 및 콜백을 실행하고 네트워크 IO 연산을 수행하며 자식 프로세스를 실행합니다.

응용 프로그램 개발자는 일반적으로 `asyncio.run()`과 같은 고수준의 asyncio 함수를 사용해야 하며, 루프 객체를 참조하거나 메서드를 호출할 필요가 거의 없습니다. 이 절은 주로 이벤트 루프 동작을 세부적으로 제어해야 하는 저수준 코드, 라이브러리 및 프레임워크의 작성자를 대상으로 합니다.

이벤트 루프 얻기

다음 저수준 함수를 사용하여 이벤트 루프를 가져오거나 설정하거나 만들 수 있습니다.:

`asyncio.``get_running_loop`()

  현재 OS 스레드에서 실행 중인 이벤트 루프를 반환합니다.

  실행 중인 이벤트 루프가 없으면 `RuntimeError`가 발생합니다. 이 함수는 코루틴이나 콜백에서만 호출할 수 있습니다.

  버전 3.7에 추가.

`asyncio.``get_event_loop`()

  Get the current event loop.

  If there is no current event loop set in the current OS thread, the OS thread is main, and `set_event_loop()` has not yet been called, asyncio will create a new event loop and set it as the current one.

  이 함수는 (특히 사용자 정의 이벤트 루프 정책을 사용할 때) 다소 복잡한 동작을 하므로, 코루틴과 콜백에서 `get_event_loop()`보다 `get_running_loop()` 함수를 사용하는 것이 좋습니다.

  저수준 함수를 사용하여 수동으로 이벤트 루프를 만들고 닫는 대신 `asyncio.run()` 함수를 사용하는 것도 고려하십시오.

`asyncio.``set_event_loop`(loop)

  loop를 현재 OS 스레드의 현재 이벤트 루프로 설정합니다.

`asyncio.``new_event_loop`()

  새 이벤트 루프 객체를 만듭니다.

`get_event_loop()`, `set_event_loop()` 및 `new_event_loop()` 함수의 동작은 사용자 정의 이벤트 루프 정책 설정에 의해 변경될 수 있음에 유의하십시오.

목차

이 설명서 페이지는 다음과 같은 절로 구성됩니다:

- 이벤트 루프 메서드 절은 이벤트 루프 API의 레퍼런스 설명서입니다.

- 콜백 핸들 절은 `loop.call_soon()` 및 `loop.call_later()`와 같은 예약 메서드에서 반환된 `Handle` 및 `TimerHandle` 인스턴스를 설명합니다.

- 서버 객체 절은 `loop.create_server()`와 같은 이벤트 루프 메서드에서 반환되는 형을 설명합니다.

- 이벤트 루프 구현 절은 `SelectorEventLoop` 및 `ProactorEventLoop` 클래스를 설명합니다.

- 예제 절에서는 일부 이벤트 루프 API로 작업하는 방법을 보여줍니다.

## 이벤트 루프 메서드

이벤트 루프에는 다음과 같은 저수준 API가 있습니다:

- 루프 실행 및 중지

- 콜백 예약하기

- 지연된 콜백 예약

- 퓨처와 태스크 만들기

- 네트워크 연결 열기

- 네트워크 서버 만들기

- 파일 전송

- TLS 업그레이드

- 파일 기술자 관찰하기

- 소켓 객체로 직접 작업하기

- DNS

- 파이프로 작업하기

- 유닉스 시그널

- 스레드 또는 프로세스 풀에서 코드를 실행하기

- 에러 처리 API

- 디버그 모드 활성화

- 자식 프로세스 실행하기

### 루프 실행 및 중지

`loop.``run_until_complete`(future)

  future(`Future`의 인스턴스)가 완료할 때까지 실행합니다.

  인자가 코루틴 객체 면, `asyncio.Task`로 실행되도록 묵시적으로 예약 됩니다.

  퓨처의 결과를 반환하거나 퓨처의 예외를 일으킵니다.

`loop.``run_forever`()

  `stop()`가 호출될 때까지 이벤트 루프를 실행합니다.

  `run_forever()` 가 호출되기 전에 `stop()` 이 호출되었으면, 루프는 시간제한 0으로 I/O 셀렉터를 한 번 폴링하고, I/O 이벤트에 따라 예약된 모든 콜백(과 이미 예약된 것들)을 실행한 다음 종료합니다.

  만약 `stop()` 이 `run_forever()` 가 실행 중일 때 호출되면, 루프는 현재 걸려있는 콜백들을 실행한 다음 종료합니다. 콜백에 의해 예약되는 새 콜백은 이 경우 실행되지 않습니다; 대신 그것들은 다음에 `run_forever()`나 `run_until_complete()`가 호출될 때 실행됩니다.

`loop.``stop`()

  이벤트 루프를 중지합니다.

`loop.``is_running`()

  이벤트 루프가 현재 실행 중이면 `True` 를 반환합니다.

`loop.``is_closed`()

  이벤트 루프가 닫혔으면 `True` 를 반환합니다.

`loop.``close`()

  이벤트 루프를 닫습니다.

  이 함수를 호출할 때 루프는 반드시 실행 중이지 않아야 합니다. 계류 중인 모든 콜백을 버립니다.

  이 메서드는 모든 큐를 비우고 실행기를 종료하지만, 실행기가 완료할 때까지 기다리지 않습니다.

  이 메서드는 멱등적(itempotent)이고 되돌릴 수 없습니다. 이벤트 루프가 닫힌 후에 다른 메서드를 호출해서는 안 됩니다.

coroutine `loop.``shutdown_asyncgens`()

  현재 열려있는 비동기 제너레이터 객체를 모두 `aclose()` 호출로 닫도록 예약 합니다. 이 메서드를 호출한 후에는, 새 비동기 생성기가 이터레이트 되면 이벤트 루프에서 경고를 보냅니다. 예약된 모든 비동기 제너레이터를 신뢰성 있게 종료하는 데 사용해야 합니다.

  `asyncio.run()`가 사용될 때 이 함수를 호출할 필요는 없다는 점에 유의하세요.

  예:

      try:
          loop.run_forever()
      finally:
          loop.run_until_complete(loop.shutdown_asyncgens())
          loop.close()

  버전 3.6에 추가.

### 콜백 예약하기

`loop.``call_soon`(callback, *args, context=None)

  이벤트 루프의 다음 이터레이션 때 args 인자로 호출할 callback을 예약합니다.

  콜백은 등록된 순서대로 호출됩니다. 각 콜백은 정확히 한 번 호출됩니다.

  선택적인 키워드 전용 context 인자는 callback 을 실행할 사용자 정의 `contextvars.Context` 를 지정할 수 있게 합니다. context 가 제공되지 않을 때는 현재 컨텍스트가 사용됩니다.

  `asyncio.Handle` 인스턴스가 반환되는데, 나중에 콜백을 취소하는 데 사용할 수 있습니다.

  이 메서드는 스레드 안전하지 않습니다.

`loop.``call_soon_threadsafe`(callback, *args, context=None)

  스레드 안전한 `call_soon()` 변형입니다. 다른 스레드에서 콜백을 예약하는 데 사용해야 합니다.

  설명서의 동시성과 다중 스레딩 절을 참고하십시오.

버전 3.7에서 변경: context 키워드 전용 매개 변수가 추가되었습니다. 자세한 정보는 PEP 567을 보십시오.

참고

대부분 `asyncio` 예약 함수는 키워드 인자 전달을 허용하지 않습니다. 그렇게 하려면 `functools.partial()`을 사용하십시오:

    # will schedule "print("Hello", flush=True)"
    loop.call_soon(
        functools.partial(print, "Hello", flush=True))

asyncio는 디버그 및 오류 메시지에서 partial 객체를 더욱 잘 표시할 수 있으므로, partial 객체를 사용하는 것이 람다를 사용하는 것보다 편리합니다.

### 지연된 콜백 예약

이벤트 루프는 콜백 함수가 미래의 어떤 시점에서 호출되도록 예약하는 메커니즘을 제공합니다. 이벤트 루프는 단조 시계를 사용하여 시간을 추적합니다.

`loop.``call_later`(delay, callback, *args, context=None)

  지정된 delay 초 (int 또는 float) 뒤에 callback 이 호출되도록 예약합니다.

  `asyncio.TimerHandle` 의 인스턴스가 반환되는데, 콜백을 취소하는 데 사용할 수 있습니다.

  callback 은 정확히 한번 호출됩니다. 두 콜백이 정확히 같은 시간에 예약되면, 어떤 것이 먼저 호출되는지는 정의되지 않습니다.

  선택적 위치 args 는 호출 될 때 콜백에 전달됩니다. 콜백을 키워드 인자로 호출하고 싶으면 `functools.partial()` 를 사용하십시오.

  선택적인 키워드 전용 context 인자는 callback 을 실행할 사용자 정의 `contextvars.Context` 를 지정할 수 있게 합니다. context 가 제공되지 않을 때는 현재 컨텍스트가 사용됩니다.

  버전 3.7에서 변경: context 키워드 전용 매개 변수가 추가되었습니다. 자세한 정보는 PEP 567을 보십시오.

  버전 3.7.1에서 변경: 파이썬 3.7.0 및 이전 버전에서 기본 이벤트 루프 구현을 사용할 때, delay는 하루를 초과할 수 없었습니다. 이 문제는 파이썬 3.7.1에서 수정되었습니다.

`loop.``call_at`(when, callback, *args, context=None)

  지정된 절대 타임스탬프 when(int 또는 float)에 callback 이 호출되도록 예약합니다. `loop.time()` 과 같은 시간 참조를 사용하십시오.

  이 메서드의 동작은 `call_later()`와 같습니다.

  `asyncio.TimerHandle` 의 인스턴스가 반환되는데, 콜백을 취소하는 데 사용할 수 있습니다.

  버전 3.7에서 변경: context 키워드 전용 매개 변수가 추가되었습니다. 자세한 정보는 PEP 567을 보십시오.

  버전 3.7.1에서 변경: 파이썬 3.7.0 및 이전 버전에서 기본 이벤트 루프 구현을 사용할 때, when와 현재 시각의 차이는 하루를 초과할 수 없었습니다. 이 문제는 파이썬 3.7.1에서 수정되었습니다.

`loop.``time`()

  이벤트 루프의 내부 단조 시계에 따라, `float` 값으로 현재 시각을 반환합니다.

참고

버전 3.8에서 변경: 파이썬 3.7 및 이전 버전에서 제한 시간(상대적인 delay 나 절대적인 when)은 1일을 초과하지 않아야 했습니다. 이 문제는 파이썬 3.8에서 수정되었습니다.

더 보기

`asyncio.sleep()` 함수.

### 퓨처와 태스크 만들기

`loop.``create_future`()

  이벤트 루프에 연결된 `asyncio.Future` 객체를 만듭니다.

  이것이 asyncio에서 퓨처를 만드는 데 선호되는 방법입니다. 이렇게 하면 제삼자 이벤트 루프가 Future 객체의 다른 구현(더 나은 성능이나 계측(instrumentation))을 제공할 수 있습니다

  버전 3.5.2에 추가.

`loop.``create_task`(coro)

  코루틴 의 실행을 예약합니다. `Task` 객체를 반환합니다.

  제삼자 이벤트 루프는 상호 운용성을 위해 자신만의 `Task` 의 서브 클래스를 사용할 수 있습니다. 이 경우, 결과 형은 `Task` 의 서브 클래스입니다.

`loop.``set_task_factory`(factory)

  `loop.create_task()` 에 의해 사용되는 태스크 팩토리를 설정합니다.

  factory 가 `None` 이면 기본 태스크 팩토리가 설정됩니다. 그렇지 않으면, factory 는 반드시 콜러블 이어야 하고, `(loop, coro)` 과 일치하는 서명을 가져야 합니다. 여기서 loop 는 활성 이벤트 루프에 대한 참조가 되고, coro 는 코루틴 객체가 됩니다. 콜러블은 `asyncio.Future` 호환 객체를 반환해야 합니다.

`loop.``get_task_factory`()

  태스크 팩토리를 반환하거나, 기본값이 사용 중이면 `None` 을 반환합니다.

### 네트워크 연결 열기

coroutine `loop.``create_connection`(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None)

  주어진 host 와 port로 지정된 주소로의 스트리밍 트랜스포트 연결을 엽니다.

  소켓 패밀리는 host(또는 지정된 경우 family)에 따라 `AF_INET` 또는 `AF_INET6`일 수 있습니다.

  소켓 유형은 `SOCK_STREAM`이 됩니다.

  protocol_factory 는 반드시 asyncio 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  이 메서드는 백그라운드에서 연결을 맺으려고 시도합니다. 성공하면, `(transport, protocol)` 쌍을 반환합니다.

  하부 연산의 시간순 개요는 다음과 같습니다:

  1. 연결이 맺어지고, 이를 위한 트랜스포트(transport) 가 만들어집니다.

  2. protocol_factory 가 인자 없이 호출되고, 프로토콜(protocol) 인스턴스를 반환할 것으로 기대됩니다.

  3. 프로토콜 인스턴스는 `connection_made()` 메서드를 호출함으로써 트랜스포트와 연결됩니다.

  4. 성공하면 `(transport, protocol)` 튜플이 반환됩니다.

  만들어진 트랜스포트는 구현 의존적인 양방향 스트림입니다.

  다른 인자들:

  - ssl: 주어지고 거짓이 아니면, SSL/TLS 트랜스포트가 만들어집니다 (기본적으로는 평범한 TCP 트랜스포트가 만들어집니다). ssl 이 `ssl.SSLContext` 객체면, 트랜스포트를 만들 때 이 컨텍스트가 사용됩니다; ssl 이 `True` 면, `ssl.create_default_context()` 가 반환하는 기본 컨텍스트가 사용됩니다.

    더 보기

    SSL/TLS 보안 고려 사항

  - server_hostname는 대상 서버의 인증서가 일치될 호스트 이름을 설정하거나 대체합니다. ssl이 `None`이 아닐 때만 전달되어야 합니다. 기본적으로 host 인자의 값이 사용됩니다. host 가 비어 있으면, 기본값이 없고 server_hostname 값을 전달해야 합니다. server_hostname 이 빈 문자열이면, 호스트 이름 일치가 비활성화됩니다 (이것은 심각한 보안 위험으로, 잠재적인 중간자 공격을 허용하게 됩니다).

  - family, proto, flags 는 host 결정을 위해 getaddrinfo() 에 전달할 선택적 주소 패밀리, 프로토콜, 플래그입니다. 주어지면, 이것들은 모두 해당하는 `socket` 모듈 상수에 대응하는 정수여야 합니다.

  - sock 이 주어지면, 트랜스포트가 사용할, 기존의 이미 연결된 `socket.socket` 객체여야 합니다. sock 이 주어지면, host, port, family, proto, flags, local_addr 를 지정해서는 안 됩니다.

  - local_addr 이 주어지면, 소켓을 로컬에 바인드 하는데 사용되는 `(local_host, local_port)` 튜플이어야 합니다. local_host 와 local_port 는 host 및 port 와 유사하게 `getaddrinfo()` 를 사용하여 조회됩니다.

  - ssl_handshake_timeout 은 (TLS 연결의 경우) 연결을 중단하기 전에 TLS 핸드 셰이크가 완료될 때까지 대기하는 시간(초)입니다. `None` (기본값) 이면 `60.0` 초가 사용됩니다.

  버전 3.7에 추가: ssl_handshake_timeout 매개 변수.

  버전 3.6에서 변경: 소켓 옵션 `TCP_NODELAY`는 기본적으로 모든 TCP 연결에 대해 설정됩니다.

  버전 3.5에서 변경: `ProactorEventLoop`에 SSL/TLS에 대한 지원이 추가되었습니다.

  더 보기

  `open_connection()` 함수는 고수준 대안 API입니다. async/await 코드에서 직접 사용할 수 있는 (`StreamReader`, `StreamWriter`) 쌍을 반환합니다.

coroutine `loop.``create_datagram_endpoint`(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)

  참고

  The parameter reuse_address is no longer supported, as using `SO_REUSEADDR` poses a significant security concern for UDP. Explicitly passing `reuse_address=True` will raise an exception.

  When multiple processes with differing UIDs assign sockets to an indentical UDP socket address with `SO_REUSEADDR`, incoming packets can become randomly distributed among the sockets.

  For supported platforms, reuse_port can be used as a replacement for similar functionality. With reuse_port, `SO_REUSEPORT` is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address.

  데이터 그램 연결을 만듭니다.

  소켓 패밀리는 host(또는 주어지면 family)에 따라 `AF_INET`, `AF_INET6` 또는 `AF_UNIX`일 수 있습니다.

  소켓 유형은 `SOCK_DGRAM`이 됩니다.

  protocol_factory 는 반드시 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  성공하면 `(transport, protocol)` 튜플이 반환됩니다.

  다른 인자들:

  - local_addr 이 주어지면, 소켓을 로컬에 바인드 하는 데 사용되는 `(local_host, local_port)` 튜플입니다. local_host 와 local_port 는 `getaddrinfo()`를 사용하여 조회됩니다.

  - remote_addr 이 주어지면, 소켓을 원격 주소에 연결하는 데 사용되는 `(remote_host, remote_port)` 튜플입니다. remote_host 와 remote_port 는 `getaddrinfo()`를 사용하여 조회됩니다.

  - family, proto, flags 는 host 결정을 위해 `getaddrinfo()` 에 전달할 선택적 주소 패밀리, 프로토콜, 플래그입니다. 주어지면, 이것들은 모두 해당하는 `socket` 모듈 상수에 대응하는 정수여야 합니다.

  - reuse_port 는 모두 만들 때 이 플래그를 설정하는 한, 이 말단이 다른 기존 말단이 바인드 된 것과 같은 포트에 바인드 되도록 허용하도록 커널에 알려줍니다. 이 옵션은 윈도우나 일부 유닉스에서는 지원되지 않습니다. `SO_REUSEPORT` 상수가 정의되어 있지 않으면, 이 기능은 지원되지 않는 것입니다.

  - allow_broadcast 는 이 말단이 브로드캐스트 주소로 메시지를 보낼 수 있도록 커널에 알립니다.

  - sock 은 트랜스포트가 사용할 소켓 객체로, 기존의 이미 연결된 `socket.socket` 객체를 사용하기 위해 선택적으로 지정할 수 있습니다. 지정되면 local_addr 과 remote_addr 를 생략해야 합니다 (반드시 `None` 이어야 합니다).

  윈도우에서, `ProactorEventLoop`를 사용할 때, 이 메서드는 지원되지 않습니다.

  UDP 메아리 클라이언트 프로토콜 과 UDP 메아리 서버 프로토콜 예제를 참고하세요.

  버전 3.4.4에서 변경: family, proto, flags, reuse_address, reuse_port, allow_broadcast, sock 매개 변수가 추가되었습니다.

  버전 3.7.6에서 변경: The reuse_address parameter is no longer supported due to security concerns.

coroutine `loop.``create_unix_connection`(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)

  유닉스 연결을 만듭니다.

  소켓 패밀리는 `AF_UNIX`가 됩니다; 소켓 유형은 `SOCK_STREAM`이 됩니다.

  성공하면 `(transport, protocol)` 튜플이 반환됩니다.

  path 는 유닉스 도메인 소켓의 이름이며, sock 매개 변수가 지정되지 않으면 필수입니다. 추상 유닉스 소켓, `str`, `bytes`, `Path` 경로가 지원됩니다.

  이 메서드의 인자에 관한 정보는 `loop.create_connection()` 메서드의 설명서를 참조하십시오.

  가용성: 유닉스.

  버전 3.7에 추가: ssl_handshake_timeout 매개 변수.

  버전 3.7에서 변경: path 매개 변수는 이제 경로류 객체 가 될 수 있습니다.

### 네트워크 서버 만들기

coroutine `loop.``create_server`(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, start_serving=True)

  host 주소의 port 에서 리스닝하는 TCP 서버(소켓 유형 `SOCK_STREAM`)를 만듭니다.

  `Server` 객체를 반환합니다.

  인자:

  - protocol_factory 는 반드시 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  - host 매개 변수는 서버가 리스닝할 위치를 결정하는 여러 형으로 설정할 수 있습니다.:

    - host가 문자열이면, TCP 서버는 host로 지정된 단일 네트워크 인터페이스에 바인딩 됩니다.

    - host가 문자열의 시퀀스면, TCP 서버는 시퀀스로 지정된 모든 네트워크 인터페이스에 바인딩 됩니다.

    - host가 빈 문자열이거나 `None`이면, 모든 인터페이스가 사용되는 것으로 가정하고, 여러 소켓의 리스트가 반환됩니다 (대체로 IPv4 하나와 IPv6 하나).

  - family 는 `socket.AF_INET` 또는 `AF_INET6` 중 하나로 설정되어, 소켓이 IPv4 또는 IPv6을 사용하게 할 수 있습니다. 설정되지 않으면, family 는 호스트 이름에 의해 결정됩니다(기본값 `socket.AF_UNSPEC`).

  - flags 은 `getaddrinfo()`를 위한 비트 마스크입니다.

  - sock 은 기존 소켓 객체를 사용하기 위해 선택적으로 지정할 수 있습니다. 지정되면, host 및 port 는 지정할 수 없습니다.

  - backlog 는 `listen()` 으로 전달되는 최대 대기 연결 수 입니다 (기본값은 100).

  - ssl 을 `SSLContext` 인스턴스로 설정하면, 들어오는 연결에 TLS를 사용합니다.

  - reuse_address 는, 일반적인 시간제한이 만료될 때까지 기다리지 않고, `TIME_WAIT` 상태의 로컬 소켓을 재사용하도록 커널에 알려줍니다. 지정하지 않으면 유닉스에서 자동으로 `True` 로 설정됩니다.

  - reuse_port 는 모두 만들 때 이 플래그를 설정하는 한, 이 말단이 다른 기존 말단이 바인드 된 것과 같은 포트에 바인드 되도록 허용하도록 커널에 알려줍니다. 이 옵션은 윈도우에서 지원되지 않습니다.

  - ssl_handshake_timeout 은 (TLS 서버의 경우) 연결을 중단하기 전에 TLS 핸드 셰이크가 완료될 때까지 대기하는 시간(초)입니다. `None` (기본값) 이면 `60.0` 초가 사용됩니다.

  - start_serving 을 `True` (기본값) 로 설정하면, 생성된 서버가 즉시 연결을 받아들입니다. `False` 로 설정되면, 사용자는 서버가 연결을 받기 시작하도록 `Server.start_serving()` 이나 `Server.serve_forever()`를 await 해야 합니다.

  버전 3.7에 추가: ssl_handshake_timeout 과 start_serving 매개 변수 추가.

  버전 3.6에서 변경: 소켓 옵션 `TCP_NODELAY`는 기본적으로 모든 TCP 연결에 대해 설정됩니다.

  버전 3.5에서 변경: `ProactorEventLoop`에 SSL/TLS에 대한 지원이 추가되었습니다.

  버전 3.5.1에서 변경: host 매개 변수는 문자열의 시퀀스가 될 수 있습니다.

  더 보기

  `start_server()` 함수는 async/await 코드에서 사용할 수 있는 `StreamReader` 및 `StreamWriter` 쌍을 반환하는 고수준의 대체 API입니다.

coroutine `loop.``create_unix_server`(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, start_serving=True)

  `loop.create_server()`와 유사하지만, 소켓 패밀리 `AF_UNIX` 용입니다.

  path 는 유닉스 도메인 소켓의 이름이며, sock 매개 변수가 제공되지 않으면 필수입니다. 추상 유닉스 소켓, `str`, `bytes`, `Path` 경로가 지원됩니다.

  이 메서드의 인자에 대한 정보는 `loop.create_server()` 메서드의 설명서를 참조하십시오.

  가용성: 유닉스.

  버전 3.7에 추가: ssl_handshake_timeout 과 start_serving 매개 변수.

  버전 3.7에서 변경: path 매개 변수는 이제 `Path` 객체일 수 있습니다.

coroutine `loop.``connect_accepted_socket`(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None)

  이미 받아들인 연결을 트랜스포트/프로토콜 쌍으로 래핑합니다.

  이 메서드는 asyncio 밖에서 연결을 받아들이지만, 그 연결을 처리하는데 asyncio 를 사용하는 서버에서 사용됩니다.

  매개 변수:

  - protocol_factory 는 반드시 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  - sock 은 `socket.accept` 가 반환한 기존 소켓 객체입니다.

  - ssl 을 `SSLContext` 로 설정하면, 들어오는 연결에 SSL을 사용합니다.

  - ssl_handshake_timeout 은 (SSL 연결의 경우) 연결을 중단하기 전에 SSL 핸드 셰이크가 완료될 때까지 대기하는 시간(초)입니다. `None` (기본값) 이면 `60.0` 초가 사용됩니다.

  `(transport, protocol)` 쌍을 반환합니다.

  버전 3.7에 추가: ssl_handshake_timeout 매개 변수.

  버전 3.5.3에 추가.

### 파일 전송

coroutine `loop.``sendfile`(transport, file, offset=0, count=None, *, fallback=True)

  file 을 transport 로 보냅니다. 전송된 총 바이트 수를 반환합니다.

  이 메서드는 가능한 경우 고성능 `os.sendfile()` 을 사용합니다.

  file 는 바이너리 모드로 열린 일반 파일 객체여야 합니다.

  offset 은 파일 읽기 시작할 위치를 알려줍니다. count 를 제공하면, EOF에 도달할 때까지 파일을 보내는 대신, 전송할 총 바이트 수를 지정합니다. 파일의 위치가 갱신됩니다, 이 메서드가 에러를 일으킬 때조차. 그리고, `file.tell()` 는 실제 전송된 바이트 수를 얻는 데 사용될 수 있습니다.

  fallback 을 `True` 로 설정하면, 플랫폼이 sendfile 시스템 호출을 지원하지 않을 때 (가령 유닉스에서 SSL 소켓을 사용하거나 윈도우인 경우), asyncio 가 파일을 수동으로 읽고 보내도록 합니다.

  시스템이 sendfile 시스템 호출을 지원하지 않고 fallback 이 `False` 면 `SendfileNotAvailableError` 를 발생시킵니다.

  버전 3.7에 추가.

### TLS 업그레이드

coroutine `loop.``start_tls`(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None)

  기존 트랜스포트 기반 연결을 TLS로 업그레이드합니다.

  protocol 이 await 의 직후에 사용해야 하는 새로운 트랜스포트 인스턴스를 반환합니다. start_tls 메서드에 전달된 transport 인스턴스는 절대로 다시 사용해서는 안 됩니다.

  매개 변수:

  - `create_server()`와 `create_connection()` 같은 메서드가 반환하는 transport 와 protocol 인스턴스.

  - sslcontext: 구성된 `SSLContext` 의 인스턴스.

  - (`create_server()` 에 의해 생성된 것과 같은) 서버 측 연결이 업그레이드될 때 server_side 에 `True` 를 전달합니다.

  - server_hostname: 대상 서버의 인증서가 일치될 호스트 이름을 설정하거나 대체합니다.

  - ssl_handshake_timeout 은 (TLS 연결의 경우) 연결을 중단하기 전에 TLS 핸드 셰이크가 완료될 때까지 대기하는 시간(초)입니다. `None` (기본값) 이면 `60.0` 초가 사용됩니다.

  버전 3.7에 추가.

### 파일 기술자 관찰하기

`loop.``add_reader`(fd, callback, *args)

  fd 파일 기술자가 읽기 가능한지 관찰하기 시작하고, 일단 fd가 읽기 가능해지면 지정한 인자로 callback 을 호출합니다.

`loop.``remove_reader`(fd)

  fd 파일 기술자가 읽기 가능한지 관찰하는 것을 중단합니다.

`loop.``add_writer`(fd, callback, *args)

  fd 파일 기술자가 쓰기 가능한지 관찰하기 시작하고, 일단 fd가 쓰기 가능해지면 지정한 인자로 callback 을 호출합니다.

  callback 에 키워드 인자를 전달하려면 `functools.partial()`를 사용하십시오.

`loop.``remove_writer`(fd)

  fd 파일 기술자가 쓰기 가능한지 관찰하는 것을 중단합니다.

이 메서드의 일부 제한 사항은 플랫폼 지원 절을 참조하십시오.

### 소켓 객체로 직접 작업하기

일반적으로 `loop.create_connection()` 및 `loop.create_server()`와 같은 트랜스포트 기반 API를 사용하는 프로토콜 구현은 소켓을 직접 사용하는 구현보다 빠릅니다. 그러나, 성능이 결정적이지 않고 `socket` 객체로 직접 작업하는 것이 더 편리한 사용 사례가 있습니다.

coroutine `loop.``sock_recv`(sock, nbytes)

  sock 에서 최대 nbytes 를 수신합니다. `socket.recv()` 의 비동기 버전.

  수신한 데이터를 바이트열 객체로 반환합니다.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.7에서 변경: 이 메서드가 항상 코루틴 메서드라고 설명되어왔지만, 파이썬 3.7 이전에는 `Future`를 반환했습니다. 파이썬 3.7부터, 이것은 `async def` 메서드입니다.

coroutine `loop.``sock_recv_into`(sock, buf)

  sock 에서 buf 버퍼로 데이터를 수신합니다. 블로킹 `socket.recv_into()` 메서드를 따라 만들어졌습니다.

  버퍼에 기록된 바이트 수를 돌려줍니다.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.7에 추가.

coroutine `loop.``sock_sendall`(sock, data)

  data 를 sock 소켓으로 보냅니다. `socket.sendall()` 의 비동기 버전.

  이 메서드는 data 의 모든 데이터가 송신되거나 에러가 발생할 때까지 소켓으로 계속 송신합니다. 성공하면 `None` 이 반환됩니다. 에러가 발생하면 예외가 발생합니다. 또한, 연결의 수신 단에서 성공적으로 처리한 (있기는 하다면) 데이터의 크기를 확인하는 방법은 없습니다.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.7에서 변경: 이 메서드가 항상 코루틴 메서드라고 설명되어왔지만, 파이썬 3.7 이전에는 `Future`를 반환했습니다. 파이썬 3.7부터, 이것은 `async def` 메서드입니다.

coroutine `loop.``sock_connect`(sock, address)

  sock을 address에 있는 원격 소켓에 연결합니다.

  `socket.connect()` 의 비동기 버전.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.5.2에서 변경: `address` 는 더는 결정될 필요가 없습니다. `sock_connect` 는 `socket.inet_pton()`을 호출하여 address 가 이미 결정되었는지를 검사합니다. 그렇지 않으면, `loop.getaddrinfo()` 가 address 를 결정하는 데 사용됩니다.

  더 보기

  `loop.create_connection()`과 `asyncio.open_connection()`.

coroutine `loop.``sock_accept`(sock)

  연결을 받아들입니다. 블로킹 `socket.accept()` 메서드를 따라 만들어졌습니다.

  소켓은 주소에 바인드 되어 연결을 리스닝해야 합니다. 반환 값은 `(conn, address)` 쌍인데, conn 은 연결로 데이터를 주고받을 수 있는 새 소켓 객체이고, address 는 연결의 반대편 끝의 소켓에 바인드 된 주소입니다.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.7에서 변경: 이 메서드가 항상 코루틴 메서드라고 설명되어왔지만, 파이썬 3.7 이전에는 `Future`를 반환했습니다. 파이썬 3.7부터, 이것은 `async def` 메서드입니다.

  더 보기

  `loop.create_server()`와 `start_server()`.

coroutine `loop.``sock_sendfile`(sock, file, offset=0, count=None, *, fallback=True)

  가능하면 고성능 `os.sendfile` 을 사용하여 파일을 보냅니다. 전송된 총 바이트 수를 반환합니다.

  `socket.sendfile()`의 비동기 버전.

  sock 은 반드시 비 블로킹 `socket.SOCK_STREAM` `socket` 이어야 합니다.

  file 는 바이너리 모드로 열린 일반 파일 객체여야 합니다.

  offset 은 파일 읽기 시작할 위치를 알려줍니다. count 를 제공하면, EOF에 도달할 때까지 파일을 보내는 대신, 전송할 총 바이트 수를 지정합니다. 파일의 위치가 갱신됩니다, 이 메서드가 에러를 일으킬 때조차. 그리고, `file.tell()` 는 실제 전송된 바이트 수를 얻는 데 사용될 수 있습니다.

  fallback 을 `True` 로 설정하면, 플랫폼이 sendfile 시스템 호출을 지원하지 않을 때 (가령 유닉스에서 SSL 소켓을 사용하거나 윈도우인 경우), asyncio 가 파일을 수동으로 읽고 보내도록 합니다.

  시스템이 sendfile 시스템 호출을 지원하지 않고 fallback 이 `False` 면 `SendfileNotAvailableError` 를 발생시킵니다.

  sock 은 반드시 비 블로킹 소켓이어야 합니다.

  버전 3.7에 추가.

### DNS

coroutine `loop.``getaddrinfo`(host, port, *, family=0, type=0, proto=0, flags=0)

  `socket.getaddrinfo()` 의 비동기 버전.

coroutine `loop.``getnameinfo`(sockaddr, flags=0)

  `socket.getnameinfo()` 의 비동기 버전.

버전 3.7에서 변경: getaddrinfo 와 getnameinfo 메서드는 모두 코루틴 메서드라고 설명되어왔지만, 파이썬 3.7 이전에 실제로는 `asyncio.Future` 객체를 반환했습니다. 파이썬 3.7부터 두 가지 메서드 모두 코루틴입니다.

### 파이프로 작업하기

coroutine `loop.``connect_read_pipe`(protocol_factory, pipe)

  이벤트 루프에 pipe의 읽기용 끝을 등록합니다.

  protocol_factory 는 반드시 asyncio 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  pipe는 파일류 객체입니다.

  쌍 `(transport, protocol)`를 반환합니다. 여기서 transport는 `ReadTransport` 인터페이스를 지원하고, protocol은 protocol_factory에 의해 인스턴스로 만들어진 객체입니다.

  `SelectorEventLoop` 이벤트 루프를 사용하면, pipe 는 비 블로킹 모드로 설정됩니다.

coroutine `loop.``connect_write_pipe`(protocol_factory, pipe)

  이벤트 루프에 pipe의 쓰기용 끝을 등록합니다.

  protocol_factory 는 반드시 asyncio 프로토콜 구현을 반환하는 콜러블이어야 합니다.

  pipe는 파일류 객체입니다.

  쌍 `(transport, protocol)`를 반환합니다. 여기서 transport는 `WriteTransport` 인터페이스를 지원하고, protocol은 protocol_factory에 의해 인스턴스로 만들어진 객체입니다.

  `SelectorEventLoop` 이벤트 루프를 사용하면, pipe 는 비 블로킹 모드로 설정됩니다.

참고

윈도우에서 `SelectorEventLoop`는 위의 메서드들을 지원하지 않습니다. 윈도우에서는 대신 `ProactorEventLoop`를 사용하십시오.

더 보기

`loop.subprocess_exec()` 와 `loop.subprocess_shell()` 메서드.

### 유닉스 시그널

`loop.``add_signal_handler`(signum, callback, *args)

  callback을 signum 시그널의 처리기로 설정합니다.

  콜백은 다른 대기 중인 콜백과 해당 이벤트 루프의 실행 가능한 코루틴과 함께 loop에 의해 호출됩니다. `signal.signal()`을 사용하여 등록된 시그널 처리기와 달리, 이 함수로 등록된 콜백은 이벤트 루프와 상호 작용할 수 있습니다.

  시그널 번호가 유효하지 않거나 잡을 수 없으면 `ValueError` 를 발생시킵니다. 처리기를 설정하는 데 문제가 있는 경우 `RuntimeError` 를 발생시킵니다.

  callback 에 키워드 인자를 전달하려면 `functools.partial()`를 사용하십시오.

  `signal.signal()`와 마찬가지로, 이 함수는 메인 스레드에서 호출되어야 합니다.

`loop.``remove_signal_handler`(sig)

  sig 시그널의 처리기를 제거합니다.

  시그널 처리기가 제거되면 `True` 를, 주어진 시그널에 처리기가 설정되지 않았으면 `False` 를 반환합니다.

  가용성: 유닉스.

더 보기

`signal` 모듈.

### 스레드 또는 프로세스 풀에서 코드를 실행하기

awaitable `loop.``run_in_executor`(executor, func, *args)

  지정된 실행기에서 func 가 호출되도록 배치합니다.

  executor 인자는 `Executor` 인스턴스여야 합니다. executor 가 `None` 이면 기본 실행기가 사용됩니다.

  예:

      import asyncio
      import concurrent.futures

      def blocking_io():
          # File operations (such as logging) can block the
          # event loop: run them in a thread pool.
          with open('/dev/urandom', 'rb') as f:
              return f.read(100)

      def cpu_bound():
          # CPU-bound operations will block the event loop:
          # in general it is preferable to run them in a
          # process pool.
          return sum(i * i for i in range(10 ** 7))

      async def main():
          loop = asyncio.get_running_loop()

          ## Options:

          # 1. Run in the default loop's executor:
          result = await loop.run_in_executor(
              None, blocking_io)
          print('default thread pool', result)

          # 2. Run in a custom thread pool:
          with concurrent.futures.ThreadPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, blocking_io)
              print('custom thread pool', result)

          # 3. Run in a custom process pool:
          with concurrent.futures.ProcessPoolExecutor() as pool:
              result = await loop.run_in_executor(
                  pool, cpu_bound)
              print('custom process pool', result)

      asyncio.run(main())

  이 메서드는 `asyncio.Future` 객체를 반환합니다.

  func 에 키워드 인자를 전달하려면 `functools.partial()`를 사용하십시오.

  버전 3.5.3에서 변경: `loop.run_in_executor()` 는 더는 자신이 만드는 스레드 풀 실행기의 `max_workers` 를 설정하지 않습니다. 대신 스레드 풀 실행기(`ThreadPoolExecutor`)가 스스로 기본값을 설정하도록 합니다.

`loop.``set_default_executor`(executor)

  executor를 `run_in_executor()`에서 사용하는 기본 실행기로 설정합니다. executor는 `ThreadPoolExecutor`의 인스턴스여야 합니다.

  버전 3.7부터 폐지: `ThreadPoolExecutor` 인스턴스가 아닌 실행기의 사용은 폐지되었고, 파이썬 3.9에서는 에러를 일으키게 됩니다.

  executor는 반드시 `concurrent.futures.ThreadPoolExecutor`의 인스턴스여야 합니다.

### 에러 처리 API

이벤트 루프에서 예외를 처리하는 방법을 사용자 정의 할 수 있습니다.

`loop.``set_exception_handler`(handler)

  handler 를 새 이벤트 루프 예외 처리기로 설정합니다.

  handler가 `None` 이면, 기본 예외 처리기가 설정됩니다. 그렇지 않으면, handler는 반드시 `(loop, context)` 와 일치하는 서명을 가진 콜러블이어야 합니다. 여기서 `loop`는 활성 이벤트 루프에 대한 참조가 될 것이고, `context` 는 예외에 관한 세부 정보를 담고 있는 `dict` 객체가 됩니다 (context에 대한 자세한 내용은 `call_exception_handler()` 문서를 참조하십시오).

`loop.``get_exception_handler`()

  현재 예외 처리기를 반환하거나, 사용자 정의 예외 처리기가 설정되지 않았으면 `None` 을 반환합니다.

  버전 3.5.2에 추가.

`loop.``default_exception_handler`(context)

  기본 예외 처리기.

  예외가 발생하고 예외 처리기가 설정되지 않았을 때 호출됩니다. 기본 동작으로 위임하려는 사용자 정의 예외 처리기가 호출할 수 있습니다.

  context 매개 변수는 `call_exception_handler()` 에서와 같은 의미입니다.

`loop.``call_exception_handler`(context)

  현재 이벤트 루프 예외 처리기를 호출합니다.

  context 는 다음 키를 포함하는 `dict` 객체입니다 (새 키가 미래의 파이썬 버전에서 추가될 수 있습니다):

  - ‘message’: 에러 메시지;

  - ‘exception’ (선택적): 예외 객체;

  - ‘future’ (선택적): `asyncio.Future` 인스턴스;

  - ‘handle’ (선택적): `asyncio.Handle` 인스턴스;

  - ‘protocol’ (선택적): 프로토콜 인스턴스;

  - ‘transport’ (선택적): 트랜스포트 인스턴스;

  - ‘socket’ (선택적): `socket.socket` 인스턴스.

  참고

  이 메서드는 서브 클래스 된 이벤트 루프에서 재정의되지 않아야 합니다. 사용자 정의 예외 처리를 위해서는 `set_exception_handler()` 메서드를 사용하십시오.

### 디버그 모드 활성화

`loop.``get_debug`()

  이벤트 루프의 디버그 모드(`bool`)를 가져옵니다.

  기본값은 환경 변수 `PYTHONASYNCIODEBUG` 가 비어 있지 않은 문자열로 설정되면 `True` 이고, 그렇지 않으면 `False` 입니다.

`loop.``set_debug`(enabled: bool)

  이벤트 루프의 디버그 모드를 설정합니다.

  버전 3.7에서 변경: 이제 새로운 `-X dev` 명령 줄 옵션을 사용하여 디버그 모드를 활성화할 수 있습니다.

더 보기

asyncio의 디버그 모드.

### 자식 프로세스 실행하기

이 하위 절에서 설명하는 메서드는 저수준입니다. 일반적인 async/await 코드에서는 대신 고수준의 `asyncio.create_subprocess_shell()` 및 `asyncio.create_subprocess_exec()` 편리 함수를 사용하는 것을 고려하십시오.

참고

Windows 의 기본 asyncio 이벤트 루프는 자식 프로세스를 지원하지 않습니다. 자세한 내용은 윈도우에서의 자식 프로세스 지원을 참조하십시오.

coroutine `loop.``subprocess_exec`(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

  args로 지정된 하나 이상의 문자열 인자로 서브 프로세스를 만듭니다.

  args는 반드시 다음과 같은 것으로 표현되는 문자열의 목록이어야 합니다:

  - `str`;

  - 또는 파일 시스템 인코딩으로로 인코딩된 `bytes`.

  첫 번째 문자열은 프로그램 실행 파일을 지정하고, 나머지 문자열은 인자를 지정합니다. 함께, 문자열 인자들은 프로그램의 `argv`를 구성합니다.

  이것은 `shell=False`와 문자열의 목록을 첫 번째 인자로 호출된 표준 라이브러리 `subprocess.Popen` 클래스와 유사합니다. 그러나 `Popen`이 문자열 목록인 단일 인자를 받아들이지만, subprocess_exec는 여러 문자열 인자를 받아들입니다.

  protocol_factory는 반드시 `asyncio.SubprocessProtocol` 클래스의 서브 클래스를 반환하는 콜러블이어야 합니다.

  다른 매개 변수:

  - stdin: `connect_write_pipe()`를 사용하여 자식 프로세스의 표준 입력 스트림에 연결될 파이프를 나타내는 파일류 객체 또는 `subprocess.PIPE` 상수 (기본값). 기본적으로 새 파이프가 만들어지고 연결됩니다.

  - stdout: `connect_read_pipe()`를 사용하여 자식 프로세스의 표준 출력 스트림에 연결될 파이프를 나타내는 파일류 객체 또는 `subprocess.PIPE` 상수 (기본값). 기본적으로 새 파이프가 만들어지고 연결됩니다.

  - stderr: `connect_read_pipe()`를 사용하여 자식 프로세스의 표준 에러 스트림에 연결될 파이프를 나타내는 파일류 객체 또는 `subprocess.PIPE` (기본값) 또는 `subprocess.STDOUT` 상수 중 하나.

    기본적으로 새 파이프가 만들어지고 연결됩니다. `subprocess.STDOUT`가 지정되면, 자식 프로세스의 표준 에러 스트림은 표준 출력 스트림과 같은 파이프에 연결됩니다.

  - 다른 모든 키워드 인자는 해석 없이 `subprocess.Popen`로 전달됩니다. 다만, bufsize, universal_newlines 및 shell은 예외인데, 이것들은 지정되지 않아야 합니다.

  다른 인자에 관한 설명은 `subprocess.Popen` 클래스의 생성자를 참조하십시오.

  `(transport, protocol)` 쌍을 반환합니다. 여기에서 transport는 `asyncio.SubprocessTransport` 베이스 클래스를 따르고, protocol은 protocol_factory에 의해 인스턴스로 만들어진 객체입니다.

coroutine `loop.``subprocess_shell`(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

  플랫폼의 “셸” 구문을 사용하는 cmd로 자식 프로세스를 만듭니다. cmd는 `str`이나 파일 시스템 인코딩으로 인코딩된 `bytes` 일 수 있습니다.

  이것은 `shell=True`로 호출된 표준 라이브러리 `subprocess.Popen` 클래스와 유사합니다.

  protocol_factory는 반드시 `SubprocessProtocol` 클래스의 서브 클래스를 반환하는 콜러블이어야 합니다.

  나머지 인자에 관한 자세한 내용은 `subprocess_exec()`를 참조하십시오.

  `(transport, protocol)` 쌍을 반환합니다. 여기서 transport는 `SubprocessTransport` 베이스 클래스를 따르고, protocol은 protocol_factory에 의해 인스턴스로 만들어진 객체입니다.

참고

셸 주입 취약점을 피하고자 모든 공백과 특수 문자를 적절하게 따옴표 처리하는 것은 응용 프로그램의 책임입니다. `shlex.quote()` 함수를 사용하여 셸 명령을 구성하는 데 사용될 문자열에 있는 공백 및 특수 문자를 올바르게 이스케이프 할 수 있습니다.

## 콜백 핸들

class `asyncio.``Handle`

  `loop.call_soon()`, `loop.call_soon_threadsafe()` 에 의해 반환되는 콜백 래퍼 객체.

  `cancel`()

    콜백을 취소합니다. 콜백이 이미 취소되었거나 실행되었다면 이 메서드는 아무 효과가 없습니다.

  `cancelled`()

    콜백이 취소되었으면 `True` 을 반환합니다.

    버전 3.7에 추가.

class `asyncio.``TimerHandle`

  `loop.call_later()` 및 `loop.call_at()` 에 의해 반환되는 콜백 래퍼 객체.

  이 클래스는 `Handle`의 서브 클래스입니다.

  `when`()

    예약된 콜백 시간을 `float` 초로 반환합니다.

    시간은 절대 타임스탬프입니다. `loop.time()` 과 같은 시간 참조를 사용합니다.

    버전 3.7에 추가.

## 서버 객체

Server 객체는 `loop.create_server()`, `loop.create_unix_server()`, `start_server()`, `start_unix_server()`로 만듭니다.

클래스의 인스턴스를 직접 만들지 마십시오.

class `asyncio.``Server`

  Server 객체는 비동기 컨텍스트 관리자입니다. `async with` 문에서 사용될 때, `async with` 문이 완료되면 서버 객체가 닫혀 있고 새 연결을 받아들이지 않는다는 것이 보장됩니다:

      srv = await loop.create_server(...)

      async with srv:
          # some code

      # At this point, srv is closed and no longer accepts new connections.

  버전 3.7에서 변경: Server 객체는 파이썬 3.7부터 비동기 컨텍스트 관리자입니다.

  `close`()

    서버를 중지합니다: 리스닝 소켓을 닫고 `sockets` 어트리뷰트를 `None` 으로 설정합니다.

    이미 받아들여진 클라이언트 연결을 나타내는 소켓은 열린 채로 있습니다.

    서버는 비동기적으로 닫힙니다. 서버가 닫힐 때까지 대기하려면 `wait_closed()` 코루틴을 사용하십시오.

  `get_loop`()

    서버 객체와 연관된 이벤트 루프를 반환합니다.

    버전 3.7에 추가.

  coroutine `start_serving`()

    연결을 받아들이기 시작합니다.

    이 메서드는 멱등적이라서, 서버가 이미 시작되었을 때도 호출 할 수 있습니다.

    `loop.create_server()`와 `asyncio.start_server()` 의 start_serving 키워드 전용 매개 변수는 즉시 연결을 받아들이지 않는 서버 객체를 만들 수 있도록 합니다. 이 경우 `Server.start_serving()`, 또는 `Server.serve_forever()`를 사용하여 Server가 연결을 받아들이기 시작하도록 할 수 있습니다.

    버전 3.7에 추가.

  coroutine `serve_forever`()

    코루틴이 취소될 때까지 연결을 받아들이기 시작합니다. `serve_forever` 태스크를 취소하면 서버가 닫힙니다.

    이 메서드는 서버가 이미 연결을 받아들이고 있어도 호출 할 수 있습니다. 하나의 Server 객체 당 하나의 `serve_forever` 태스크만 존재할 수 있습니다.

    예:

        async def client_connected(reader, writer):
            # Communicate with the client with
            # reader/writer streams.  For example:
            await reader.readline()

        async def main(host, port):
            srv = await asyncio.start_server(
                client_connected, host, port)
            await srv.serve_forever()

        asyncio.run(main('127.0.0.1', 0))

    버전 3.7에 추가.

  `is_serving`()

    서버가 새 연결을 받아들이고 있으면 `True` 를 반환합니다.

    버전 3.7에 추가.

  coroutine `wait_closed`()

    `close()` 메서드가 완료될 때까지 기다립니다.

  `sockets`

    서버가 리스닝하고 있는 `socket.socket` 객체의 리스트, 또는 서버가 닫혀 있다면 `None`.

    버전 3.7에서 변경: 파이썬 3.7 이전에는 `Server.sockets` 가 서버 소켓의 내부 리스트를 직접 반환했습니다. 3.7에서는 그 리스트의 복사본이 반환됩니다.

## 이벤트 루프 구현

asyncio에는 두 가지 이벤트 루프 구현이 함께 제공됩니다: `SelectorEventLoop` 및 `ProactorEventLoop`.

기본적으로 asyncio는 모든 플랫폼에서 `SelectorEventLoop`를 사용하도록 구성됩니다.

class `asyncio.``SelectorEventLoop`

  `selectors` 모듈을 기반으로 하는 이벤트 루프.

  주어진 플랫폼에서 사용할 수 있는 가장 효율적인 selector를 사용합니다. 정확한 셀렉터 구현을 수동으로 구성하여 사용할 수도 있습니다.:

      import asyncio
      import selectors

      selector = selectors.SelectSelector()
      loop = asyncio.SelectorEventLoop(selector)
      asyncio.set_event_loop(loop)

  가용성: 유닉스, 윈도우.

class `asyncio.``ProactorEventLoop`

  “I/O 완료 포트”(IOCP)를 사용하는 윈도우용 이벤트 루프.

  가용성: 윈도우.

  윈도우에서 `ProactorEventLoop`를 사용하는 예:

      import asyncio
      import sys

      if sys.platform == 'win32':
          loop = asyncio.ProactorEventLoop()
          asyncio.set_event_loop(loop)

  더 보기

  I/O 완료 포트에 관한 MSDN 설명서.

class `asyncio.``AbstractEventLoop`

  asyncio 호환 이벤트 루프의 추상 베이스 클래스.

  이벤트 루프 메서드 절은 `AbstractEventLoop`의 다른 구현이 정의해야 하는 모든 메서드를 나열합니다.

## 예제

이 절의 모든 예는 의도적으로 `loop.run_forever()` 및 `loop.call_soon()`와 같은 저수준 이벤트 루프 API를 사용하는 방법을 보여줍니다. 현대 asyncio 응용 프로그램은 거의 이런 식으로 작성할 필요가 없습니다; `asyncio.run()`과 같은 고수준 함수를 사용하는 것을 고려하십시오.

### call_soon()을 사용하는 Hello World

콜백을 예약하기 위해 `loop.call_soon()` 메서드를 사용하는 예제. 콜백은 `"Hello World"` 를 표시한 다음 이벤트 루프를 중지합니다:

    import asyncio

    def hello_world(loop):
        """A callback to print 'Hello World' and stop the event loop"""
        print('Hello World')
        loop.stop()

    loop = asyncio.get_event_loop()

    # Schedule a call to hello_world()
    loop.call_soon(hello_world, loop)

    # Blocking call interrupted by loop.stop()
    try:
        loop.run_forever()
    finally:
        loop.close()

더 보기

코루틴과 `run()` 함수로 작성된 유사한 Hello World 예제.

### call_later()로 현재 날짜를 표시합니다.

초마다 현재 날짜를 표시하는 콜백의 예입니다. 콜백은 `loop.call_later()` 메서드를 사용하여 5초 동안 자신을 다시 예약한 다음 이벤트 루프를 중지합니다:

    import asyncio
    import datetime

    def display_date(end_time, loop):
        print(datetime.datetime.now())
        if (loop.time() + 1.0) < end_time:
            loop.call_later(1, display_date, end_time, loop)
        else:
            loop.stop()

    loop = asyncio.get_event_loop()

    # Schedule the first call to display_date()
    end_time = loop.time() + 5.0
    loop.call_soon(display_date, end_time, loop)

    # Blocking call interrupted by loop.stop()
    try:
        loop.run_forever()
    finally:
        loop.close()

더 보기

코루틴과 `run()` 함수로 작성된 유사한 현재 날짜 예제.

### 파일 기술자에서 읽기 이벤트를 관찰하기

`loop.add_reader()` 메서드를 사용하여 파일 기술자가 데이터를 수신할 때까지 기다렸다가 이벤트 루프를 닫습니다:

    import asyncio
    from socket import socketpair

    # Create a pair of connected file descriptors
    rsock, wsock = socketpair()

    loop = asyncio.get_event_loop()

    def reader():
        data = rsock.recv(100)
        print("Received:", data.decode())

        # We are done: unregister the file descriptor
        loop.remove_reader(rsock)

        # Stop the event loop
        loop.stop()

    # Register the file descriptor for read event
    loop.add_reader(rsock, reader)

    # Simulate the reception of data from the network
    loop.call_soon(wsock.send, 'abc'.encode())

    try:
        # Run the event loop
        loop.run_forever()
    finally:
        # We are done. Close sockets and the event loop.
        rsock.close()
        wsock.close()
        loop.close()

더 보기

- 트랜스포트, 프로토콜, `loop.create_connection()` 메서드를 사용한 유사한 예제.

- 고수준의 `asyncio.open_connection()` 함수와 스트림을 사용하는 또 다른 유사한 예제.

### SIGINT 및 SIGTERM에 대한 시그널 처리기 설정

(이 `signals` 예제는 유닉스에서만 작동합니다.)

`loop.add_signal_handler()` 메서드를 사용하여 `SIGINT`와 `SIGTERM` 시그널을 위한 처리기를 등록합니다:

    import asyncio
    import functools
    import os
    import signal

    def ask_exit(signame, loop):
        print("got signal %s: exit" % signame)
        loop.stop()

    async def main():
        loop = asyncio.get_running_loop()

        for signame in {'SIGINT', 'SIGTERM'}:
            loop.add_signal_handler(
                getattr(signal, signame),
                functools.partial(ask_exit, signame, loop))

        await asyncio.sleep(3600)

    print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
    print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")

    asyncio.run(main())