# `select` — Waiting for I/O completion

이 모듈은 대부분의 운영 체제에서 사용 가능한 `select()`와 `poll()` 함수, Solaris와 파생 제품에서 사용 가능한 `devpoll()`, 리눅스 2.5+ 에서 사용 가능한 `epoll()` 및 대부분의 BSD에서 사용 가능한 `kqueue()`에 대한 액세스를 제공합니다. 윈도우에서는 소켓에서만 작동함에 유의하십시오; 다른 운영 체제에서는, 다른 파일 유형에서도 작동합니다 (특히, 유닉스에서는 파이프에서도 작동합니다). 일반 파일에서 파일을 마지막으로 읽은 이후에 파일이 커졌는지를 판별하기 위해 사용할 수는 없습니다.

참고

`selectors` 모듈은 `select` 모듈 프리미티브에 기반한 고수준의 효율적인 I/O 멀티플렉싱을 제공합니다. 사용되는 OS 수준 프리미티브에 대한 정확한 제어를 원하지 않는 한, 사용자는 `selectors` 모듈을 대신 사용하는 것이 좋습니다.

Availability: not Emscripten, not WASI.

This module does not work or is not available on WebAssembly platforms `wasm32-emscripten` and `wasm32-wasi`. See 웹어셈블리 플랫폼 for more information.

모듈은 다음을 정의합니다:

exception select.error

  `OSError`의 폐지된 별칭.

  버전 3.3에서 변경: PEP 3151에 따라, 이 클래스는 `OSError`의 별칭이 되었습니다.

select.devpoll()

  (Solaris와 파생 제품에서만 지원됩니다.) `/dev/poll` 폴링(polling) 객체를 반환합니다; devpoll 객체가 지원하는 메서드에 대해서는 아래의 /dev/poll 폴링 객체 섹션을 참조하십시오.

  `devpoll()` 객체는 인스턴스 화 시점에 허용되는 파일 기술자 수에 연결됩니다. 프로그램이 이 값을 줄이면, `devpoll()`이 실패합니다. 프로그램이 이 값을 늘리면, `devpoll()`은 불완전한 활성 파일 기술자 리스트를 반환할 수 있습니다.

  새 파일 기술자는 상속 불가능합니다.

  버전 3.3에 추가.

  버전 3.4에서 변경: 새 파일 기술자는 이제 상속 불가능합니다.

select.epoll(sizehint=-1, flags=0)

  (리눅스 2.5.44 이상에서만 지원됩니다.) I/O 이벤트를 위한 에지(Edge)나 레벨(Level) 트리거 되는 인터페이스로 사용할 수 있는 에지 폴링 객체를 반환합니다.

  sizehint는 epoll에 등록될 예상 이벤트 수를 알려줍니다. 양수이거나, 기본값을 사용하려면 `-1`이어야 합니다. `epoll_create1()`을 사용할 수 없는 구형 시스템에서만 사용됩니다; 그렇지 않으면 효과가 없습니다 (값을 여전히 확인하기는 합니다).

  flags는 폐지되었고 완전히 무시됩니다. 그러나, 제공되면, 값은 `0`이나 `select.EPOLL_CLOEXEC`여야 합니다. 그렇지 않으면 `OSError`가 발생합니다.

  epolling 객체가 지원하는 메서드는 아래의 에지와 레벨 트리거 폴링 (epoll) 객체 섹션을 참조하십시오.

  `epoll` 객체는 컨텍스트 관리자 프로토콜을 지원합니다: `with` 문에서 사용될 때, 새 파일 기술자는 블록 끝에서 자동으로 닫힙니다.

  새 파일 기술자는 상속 불가능합니다.

  버전 3.3에서 변경: flags 매개 변수를 추가했습니다.

  버전 3.4에서 변경: `with` 문에 대한 지원이 추가되었습니다. 새로운 파일 기술자는 이제 상속 불가능합니다.

  버전 3.4부터 폐지됨: flags 매개 변수. 이제 기본적으로 `select.EPOLL_CLOEXEC`가 사용됩니다. 파일 기술자를 상속 가능하게 하려면 `os.set_inheritable()`을 사용하십시오.

select.poll()

  (모든 운영 체제에서 지원되는 것은 아닙니다.) 파일 기술자 등록과 등록 해지를 지원하고 그런 다음 I/O 이벤트에 대해 폴링하는 폴링 객체를 반환합니다; 폴링 객체가 지원하는 메서드에 대해서는 아래의 폴링 객체 섹션을 참조하십시오.

select.kqueue()

  (BSD에서만 지원됩니다.) 커널 큐 객체를 반환합니다; kqueue 객체가 지원하는 메서드에 대해서는 아래의 Kqueue 객체 섹션을 참조하십시오.

  새 파일 기술자는 상속 불가능합니다.

  버전 3.4에서 변경: 새 파일 기술자는 이제 상속 불가능합니다.

select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)

  (BSD에서만 지원됩니다.) 커널 이벤트 객체를 반환합니다. kevent 객체가 지원하는 메서드에 대해서는 아래의 Kevent 객체 섹션을 참조하십시오.

select.select(rlist, wlist, xlist[, timeout])

  이것은 유닉스 `select()` 시스템 호출에 대한 간단한 인터페이스입니다. 처음 세 개의 인자는 ‘대기 가능한 객체(waitable objects)’의 이터러블입니다: 대기 가능한 객체는 파일 기술자를 나타내는 정수나 그런 정수를 반환하는 `fileno()`라는 매개 변수 없는 메서드를 가진 객체입니다:

  - rlist: 읽을 준비가 될 때까지 기다립니다

  - wlist: 쓰기 준비가 될 때까지 기다립니다

  - xlist: “예외 조건”을 기다립니다 (시스템에서 어떤 것들을 이러한 조건으로 간주하는지는 매뉴얼 페이지를 참조하십시오)

  Empty iterables are allowed, but acceptance of three empty iterables is platform-dependent. (It is known to work on Unix but not on Windows.) The optional timeout argument specifies a time-out as a floating point number in seconds. When the timeout argument is omitted the function blocks until at least one file descriptor is ready. A time-out value of zero specifies a poll and never blocks.

  반환 값은 준비된 객체의 리스트 3개입니다: 처음 세 인자의 부분 집합입니다. 파일 기술자가 준비되지 않고 시간제한에 도달하면, 세 개의 빈 리스트가 반환됩니다.

  이터러블에서 허용되는 객체 형에는 파이썬 파일 객체 (예를 들어 `sys.stdin`, 또는 `open()`이나 `os.popen()`에서 반환된 객체), `socket.socket()`에서 반환된 소켓 객체가 있습니다. 적절한 (단지 임의의 정수가 아니라 실제 파일 기술자를 반환하는) `fileno()` 메서드가 있는 한, 래퍼 (wrapper) 클래스를 직접 정의할 수도 있습니다.

  참고

  윈도우에서 파일 객체는 허용되지 않지만, 소켓은 허용됩니다. 윈도우에서, 하부 `select()` 함수는 WinSock 라이브러리에서 제공되며, WinSock에서 생성되지 않은 파일 기술자를 처리하지 않습니다.

  버전 3.5에서 변경: 시그널 처리기가 `InterruptedError`를 발생시키는 대신 예외를 발생시키는 경우(이유는 PEP 475를 참조하십시오)를 제외하고, 시그널에 의해 인터럽트 될 때 다시 계산된 시간제한으로 함수가 다시 시도됩니다.

select.PIPE_BUF

  파이프가 `select()`, `poll()` 또는 이 모듈의 다른 인터페이스에서 쓰기 준비가 된 것으로 보고될 때, 파이프를 블록 하지 않고 쓸 수 있는 최소 바이트 수. 소켓과 같은 다른 파일류 객체에는 적용되지 않습니다.

  이 값은 POSIX에서 512 이상이 되도록 보장합니다.

  Availability: Unix

  버전 3.2에 추가.

## `/dev/poll` 폴링 객체

Solaris와 파생 제품에는 `/dev/poll`이 있습니다. `select()`는 O(가장 높은 파일 기술자)이고 `poll()`은 O(파일 기술자 수)이지만 `/dev/poll`은 O(활성 파일 기술자)입니다.

`/dev/poll` 동작은 표준 `poll()` 객체에 매우 가깝습니다.

devpoll.close()

  폴링 객체의 파일 기술자를 닫습니다.

  버전 3.4에 추가.

devpoll.closed

  폴링 객체가 닫혔으면 `True`.

  버전 3.4에 추가.

devpoll.fileno()

  폴링 객체의 파일 기술자 번호를 반환합니다.

  버전 3.4에 추가.

devpoll.register(fd[, eventmask])

  폴링 객체에 파일 기술자를 등록합니다. 이후 `poll()` 메서드에 대한 호출은 파일 기술자에 계류 중인 I/O 이벤트가 있는지 확인합니다. fd는 정수이거나, 정수를 반환하는 `fileno()` 메서드가 있는 객체일 수 있습니다. 파일 객체는 `fileno()`를 구현하므로, 인자로도 사용할 수 있습니다.

  eventmask는 확인할 이벤트 유형을 설명하는 선택적 비트 마스크입니다. 상수는 `poll()` 객체와 같습니다. 기본값은 상수 `POLLIN`, `POLLPRI` 및 `POLLOUT`의 조합입니다.

  경고

  이미 등록된 파일 기술자를 등록하는 것은 에러가 아니지만, 결과는 정의되지 않습니다. 적절한 액션은 먼저 unregister 하거나 modify 하는 것입니다. 이것은 `poll()`과 비교하여 중요한 차이점입니다.

devpoll.modify(fd[, eventmask])

  이 메서드는 `unregister()` 다음에 `register()`를 수행합니다. 명시적으로 같은 작업을 수행하는 것보다 조금 더 효율적입니다.

devpoll.unregister(fd)

  폴링 객체가 추적하는 파일 기술자를 제거합니다. `register()` 메서드와 마찬가지로, fd는 정수이거나 정수를 반환하는 `fileno()` 메서드가 있는 객체일 수 있습니다.

  등록되지 않은 파일 기술자를 제거하려고 하면 안전하게 무시됩니다.

devpoll.poll([timeout])

  등록된 파일 기술자 집합을 폴링하고, 보고할 이벤트나 에러가 있는 기술자에 대한 `(fd, event)` 2-튜플이 포함된 비어있을 수 있는 리스트를 반환합니다. fd는 파일 기술자이고, event는 해당 기술자에 대해 보고된 이벤트에 대해 설정된 비트가 있는 비트 마스크입니다 — 대기 중인 입력은 `POLLIN`, 기술자에 쓸 수 있음을 나타내는 데는 `POLLOUT`, 등등. 빈 리스트는 시간제한을 초과하였고 보고할 이벤트가 있는 파일 기술자가 없음을 나타냅니다. timeout이 제공되면, 시스템이 반환하기 전에 이벤트를 기다리는 시간을 밀리초로 지정합니다. timeout을 생략하거나 -1이거나 `None`이면, 이 폴링 객체에 대한 이벤트가 있을 때까지 호출이 블록 됩니다.

  버전 3.5에서 변경: 시그널 처리기가 `InterruptedError`를 발생시키는 대신 예외를 발생시키는 경우(이유는 PEP 475를 참조하십시오)를 제외하고, 시그널에 의해 인터럽트 될 때 다시 계산된 시간제한으로 함수가 다시 시도됩니다.

## 에지와 레벨 트리거 폴링 (epoll) 객체

> https://linux.die.net/man/4/epoll

> eventmask

> 상수 | 의미
> --- | ---
> `EPOLLIN` | 읽기 가능
> `EPOLLOUT` | 쓰기 가능
> `EPOLLPRI` | 읽을 긴급 데이터
> `EPOLLERR` | 연관된 fd에서 에러 조건이 발생했습니다
> `EPOLLHUP` | 연관된 fd에서 끊어짐(hang up)이 발생했습니다
> `EPOLLET` | 에지 트리거 동작을 설정합니다, 기본값은 레벨 트리거 동작입니다
> `EPOLLONESHOT` | 원샷(one-shot) 동작을 설정합니다. 하나의 이벤트를 꺼낸 후에, fd는 내부적으로 비활성화됩니다.
> `EPOLLEXCLUSIVE` | 연관된 fd에 이벤트가 있을 때 하나의 epoll 객체만 깨웁니다. 기본값(이 플래그가 설정되지 않으면)은 fd를 폴링하는 모든 epoll 객체를 깨우는 것입니다.
> `EPOLLRDHUP` | 스트림 소켓 반대편이 연결을 닫았거나 연결의 쓰기 절반을 종료했습니다.
> `EPOLLRDNORM` | `EPOLLIN`과 동등합니다
> `EPOLLRDBAND` | 우선순위가 높은 데이터 대역을 읽을 수 있습니다.
> `EPOLLWRNORM` | `EPOLLOUT`과 동등합니다
> `EPOLLWRBAND` | 우선순위가 높은 데이터를 쓸 수 있습니다.
> `EPOLLMSG` | 무시됩니다.

> 버전 3.6에 추가: `EPOLLEXCLUSIVE`가 추가되었습니다. 리눅스 커널 4.5 이상에서만 지원됩니다.

epoll.close()

  epoll 객체의 제어 파일 기술자를 닫습니다.

epoll.closed

  epoll 객체가 닫혔으면 `True`.

epoll.fileno()

  제어 fd의 파일 기술자 번호를 반환합니다.

epoll.fromfd(fd)

  주어진 파일 기술자에서 epoll 객체를 만듭니다.

epoll.register(fd[, eventmask])

  epoll 객체에 fd 기술자를 등록합니다.

epoll.modify(fd, eventmask)

  등록된 파일 기술자를 수정합니다.

epoll.unregister(fd)

  epoll 객체에서 등록된 파일 기술자를 제거합니다.

  버전 3.9에서 변경: 이 메서드는 더는 `EBADF` 에러를 무시하지 않습니다.

epoll.poll(timeout=None, maxevents=-1)

  이벤트를 기다립니다. 시간제한은 초 단위입니다 (float)

  버전 3.5에서 변경: 시그널 처리기가 `InterruptedError`를 발생시키는 대신 예외를 발생시키는 경우(이유는 PEP 475를 참조하십시오)를 제외하고, 시그널에 의해 인터럽트 될 때 다시 계산된 시간제한으로 함수가 다시 시도됩니다.

## 폴링 객체

대부분의 유닉스 시스템에서 지원되는 `poll()` 시스템 호출은 동시에 많은 클라이언트에게 서비스를 제공하는 네트워크 서버에 더 나은 확장성을 제공합니다. `select()`는 비트맵을 빌드하고, 관심 있는 fd에 대한 비트를 켠 후, 전체 비트 맵을 다시 선형으로 스캔해야 하지만, 이 시스템 호출은 관심 있는 파일 기술자만 나열하면 되기 때문에 `poll()`은 더 잘 확장됩니다. `select()`는 O(가장 높은 파일 기술자)이고 `poll()`은 O(파일 기술자 수)입니다.

poll.register(fd[, eventmask])

  폴링 객체에 파일 기술자를 등록합니다. 이후 `poll()` 메서드에 대한 호출은 파일 기술자에 계류 중인 I/O 이벤트가 있는지 확인합니다. fd는 정수이거나, 정수를 반환하는 `fileno()` 메서드가 있는 객체일 수 있습니다. 파일 객체는 `fileno()`를 구현하므로, 인자로도 사용할 수 있습니다.

  eventmask는 확인할 이벤트 유형을 설명하는 선택적 비트 마스크이고, 아래 표에 설명된 상수 `POLLIN`, `POLLPRI` 및 `POLLOUT`의 조합일 수 있습니다. 지정하지 않으면, 사용되는 기본값은 3가지 유형의 이벤트를 모두 확인합니다.

  상수 | 의미
  --- | ---
  `POLLIN` | 읽을 데이터가 있습니다
  `POLLPRI` | 읽을 긴급한 데이터가 있습니다
  `POLLOUT` | 출력 준비: 쓰기가 블록 되지 않을 것입니다
  `POLLERR` | 어떤 종류의 에러 조건
  `POLLHUP` | 끊어졌습니다(Hung up)
  `POLLRDHUP` | 스트림 소켓 반대편이 연결을 닫았거나, 연결의 쓰기 절반을 종료했습니다
  `POLLNVAL` | 잘못된 요청: 기술자가 열리지 않았습니다

  이미 등록된 파일 기술자를 등록하는 것은 에러가 아니며, 기술자를 정확히 한 번 등록하는 것과 같은 효과가 있습니다.

poll.modify(fd, eventmask)

  이미 등록된 fd를 수정합니다. 이것은 `register(fd, eventmask)`와 같은 효과가 있습니다. 등록되지 않은 파일 기술자를 수정하려고 하면 errno `ENOENT`로 `OSError` 예외가 발생합니다.

poll.unregister(fd)

  폴링 객체가 추적하는 파일 기술자를 제거합니다. `register()` 메서드와 마찬가지로, fd는 정수이거나 정수를 반환하는 `fileno()` 메서드가 있는 객체일 수 있습니다.

  등록되지 않은 파일 기술자를 제거하려고 하면 `KeyError` 예외가 발생합니다.

poll.poll([timeout])

  등록된 파일 기술자 집합을 폴링하고, 보고할 이벤트나 에러가 있는 기술자에 대한 `(fd, event)` 2-튜플이 포함된 비어있을 수 있는 리스트를 반환합니다. fd는 파일 기술자이고, event는 해당 기술자에 대해 보고된 이벤트에 대해 설정된 비트가 있는 비트 마스크입니다 — 대기 중인 입력은 `POLLIN`, 기술자에 쓸 수 있음을 나타내는 데는 `POLLOUT`, 등등. 빈 리스트는 시간제한을 초과하였고 보고할 이벤트가 있는 파일 기술자가 없음을 나타냅니다. timeout이 제공되면, 시스템이 반환하기 전에 이벤트를 기다리는 시간을 밀리초로 지정합니다. timeout을 생략하거나 음수이거나 `None`이면, 이 폴링 객체에 대한 이벤트가 있을 때까지 호출이 블록 됩니다.

  버전 3.5에서 변경: 시그널 처리기가 `InterruptedError`를 발생시키는 대신 예외를 발생시키는 경우(이유는 PEP 475를 참조하십시오)를 제외하고, 시그널에 의해 인터럽트 될 때 다시 계산된 시간제한으로 함수가 다시 시도됩니다.

## Kqueue 객체

kqueue.close()

  kqueue 객체의 제어 파일 기술자를 닫습니다.

kqueue.closed

  kqueue 객체가 닫혔으면 `True`.

kqueue.fileno()

  제어 fd의 파일 기술자 번호를 반환합니다.

kqueue.fromfd(fd)

  주어진 파일 기술자에서 kqueue 객체를 만듭니다.

kqueue.control(changelist, max_events[, timeout]) → eventlist

  kevent에 대한 저수준 인터페이스

  - changelist는 kevent 객체의 이터러블 이거나 `None`이어야 합니다

  - max_events는 0이거나 양의 정수여야 합니다.

  - timeout은 초 단위 (float 가능); 기본값은 `None`이고 무한히 대기합니다

  버전 3.5에서 변경: 시그널 처리기가 `InterruptedError`를 발생시키는 대신 예외를 발생시키는 경우(이유는 PEP 475를 참조하십시오)를 제외하고, 시그널에 의해 인터럽트 될 때 다시 계산된 시간제한으로 함수가 다시 시도됩니다.

## Kevent 객체

https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2

kevent.ident

  이벤트를 식별하는 데 사용되는 값. 해석은 필터에 따라 다르지만, 일반적으로 파일 기술자입니다. 생성자에서 ident 는 정수이거나 `fileno()` 메서드가 있는 객체일 수 있습니다. kevent는 내부적으로 정수를 저장합니다.

kevent.filter

  커널 필터의 이름.

  상수 | 의미
  --- | ---
  `KQ_FILTER_READ` | 기술자를 취하고 읽을 수 있는 데이터가 있을 때마다 반환합니다
  `KQ_FILTER_WRITE` | 기술자를 취하고 쓸 수 있는 데이터가 있을 때마다 반환합니다
  `KQ_FILTER_AIO` | AIO 요청
  `KQ_FILTER_VNODE` | fflag에서 감시 중인 요청된 이벤트 중 하나 이상이 발생할 때 반환합니다
  `KQ_FILTER_PROC` | 프로세스 id에서 이벤트를 감시합니다
  `KQ_FILTER_NETDEV` | 네트워크 장치에서 이벤트를 감시합니다 [맥 OS에서는 사용할 수 없습니다]
  `KQ_FILTER_SIGNAL` | 감시하는 시그널이 프로세스에 전달될 때마다 반환합니다
  `KQ_FILTER_TIMER` | 임의의 타이머를 설정합니다

kevent.flags

  필터 액션.

  상수 | 의미
  --- | ---
  `KQ_EV_ADD` | 이벤트를 추가하거나 수정합니다
  `KQ_EV_DELETE` | 큐에서 이벤트를 제거합니다
  `KQ_EV_ENABLE` | 이벤트를 반환하도록 Permitscontrol() 합니다
  `KQ_EV_DISABLE` | 이벤트 비활성화
  `KQ_EV_ONESHOT` | 처음 발생한 후 이벤트를 제거합니다
  `KQ_EV_CLEAR` | 이벤트를 꺼낸 후 상태를 재설정합니다
  `KQ_EV_SYSFLAGS` | 내부 이벤트
  `KQ_EV_FLAG1` | 내부 이벤트
  `KQ_EV_EOF` | 필터 특정 EOF 조건
  `KQ_EV_ERROR` | 반환 값을 봅니다

kevent.fflags

  필터 특정 플래그.

  `KQ_FILTER_READ`와 `KQ_FILTER_WRITE` 필터 플래그:

  상수 | 의미
  --- | ---
  `KQ_NOTE_LOWAT` | 소켓 버퍼의 낮은 수위(low water mark)

  `KQ_FILTER_VNODE` 필터 플래그:

  상수 | 의미
  --- | ---
  `KQ_NOTE_DELETE` | unlink()가 호출되었습니다
  `KQ_NOTE_WRITE` | 쓰기가 발생했습니다
  `KQ_NOTE_EXTEND` | 파일이 확장되었습니다
  `KQ_NOTE_ATTRIB` | 속성이 변경되었습니다
  `KQ_NOTE_LINK` | 링크 수가 변경되었습니다
  `KQ_NOTE_RENAME` | 파일 이름이 변경되었습니다
  `KQ_NOTE_REVOKE` | 파일에 대한 액세스가 취소되었습니다

  `KQ_FILTER_PROC` 필터 플래그:

  상수 | 의미
  --- | ---
  `KQ_NOTE_EXIT` | 프로세스가 종료되었습니다
  `KQ_NOTE_FORK` | 프로세스가 fork()를 호출했습니다
  `KQ_NOTE_EXEC` | 프로세스가 새로운 프로세스를 실행했습니다
  `KQ_NOTE_PCTRLMASK` | 내부 필터 플래그
  `KQ_NOTE_PDATAMASK` | 내부 필터 플래그
  `KQ_NOTE_TRACK` | fork()를 가로질러 프로세스를 추적합니다
  `KQ_NOTE_CHILD` | NOTE_TRACK의 경우 자식 프로세스에서 반환됩니다
  `KQ_NOTE_TRACKERR` | 자식에게 연결할 수 없습니다

  `KQ_FILTER_NETDEV` 필터 플래그 (맥 OS에서는 사용할 수 없습니다):

  상수 | 의미
  --- | ---
  `KQ_NOTE_LINKUP` | 링크가 올라갔습니다
  `KQ_NOTE_LINKDOWN` | 링크가 내려갔습니다
  `KQ_NOTE_LINKINV` | 링크 상태가 유효하지 않습니다

kevent.data

  필터 특정 데이터.

kevent.udata

  사용자 정의 값.