selectors — 고수준 I/O 다중화
selectors — 고수준 I/O 다중화
versionadded: 3.4.
selectors 모듈은 select 모듈의 프리미티브 위에 구축된 고수준이고 효율적인 I/O 다중화를 가능하게 합니다. 사용자가 OS 수준의 프리미티브를 정밀하게 제어하려는 경우가 아니라면 이 모듈을 사용하는 것이 좋습니다.
본문
소개
이 모듈은 BaseSelector 추상 기본 클래스와 몇 가지 구체적인 구현(KqueueSelector, EpollSelector 등)을 정의합니다. 이들은 여러 파일 객체에 대한 I/O 준비 알림을 기다리는 데 사용할 수 있습니다. 다음에서 "파일 객체"는 fileno() 메서드가 있는 모든 객체 또는 원시 파일 디스크립터를 의미합니다. 파일 객체를 참고하세요.
DefaultSelector는 현재 플랫폼에서 사용할 수 있는 가장 효율적인 구현의 별칭입니다. 이것이 대부분의 사용자에게 기본 선택이어야 합니다.
Note
지원되는 파일 객체의 유형은 플랫폼에 따라 다릅니다: Windows에서는 소켓이 지원되지만 파이프는 지원되지 않는 반면, Unix에서는 둘 다 지원됩니다(fifo나 특수 파일 장치와 같은 다른 유형도 지원될 수 있습니다).
See also
select — 저수준 I/O 다중화 모듈.
availability: not WASI.
WebAssembly에서는 이 모듈이 작동하지 않거나 사용할 수 없습니다.
클래스
클래스 계층 구조:
BaseSelector
+-- SelectSelector
+-- PollSelector
+-- EpollSelector
+-- DevpollSelector
+-- KqueueSelector
다음에서 events는 주어진 파일 객체에서 대기해야 하는 I/O 이벤트를 나타내는 비트 마스크입니다. 모듈의 아래 상수들의 조합일 수 있습니다.
| 상수 | 의미 |
|---|---|
| selectors.EVENT_READ | 읽기 가능 |
| selectors.EVENT_WRITE | 쓰기 가능 |
selectors.SelectorKey
SelectorKey는 파일 객체를 그 기저의 파일 디스크립터, 선택된 이벤트 마스크 및 첨부된 데이터와 연관시키는 데 사용되는 namedtuple입니다. 여러 BaseSelector 메서드에 의해 반환됩니다.
- fileobj — 등록된 파일 객체.
- fd — 기저의 파일 디스크립터.
- events — 이 파일 객체에서 대기해야 하는 이벤트.
- data — 이 파일 객체와 연관된 선택적 불투명 데이터. 예를 들어 클라이언트별 세션 ID를 저장하는 데 사용할 수 있습니다.
selectors.BaseSelector
BaseSelector는 여러 파일 객체에서 I/O 이벤트 준비를 기다리는 데 사용됩니다. 파일 스트림 등록, 등록 해제, 그리고 선택적 타임아웃으로 그 스트림에서 I/O 이벤트를 기다리는 메서드를 지원합니다. 추상 기본 클래스이므로 인스턴스화할 수 없습니다. DefaultSelector를 사용하거나, 특정 구현을 사용하고 플랫폼이 지원한다면 SelectSelector, KqueueSelector 등을 사용하세요.
BaseSelector와 그 구체적인 구현은 컨텍스트 관리자 프로토콜을 지원합니다.
register(fileobj, events, data=None)
선택을 위해 파일 객체를 등록하고 I/O 이벤트를 모니터링합니다.
fileobj는 모니터링할 파일 객체입니다. 정수 파일 디스크립터이거나 fileno() 메서드가 있는 객체일 수 있습니다. events는 모니터링할 이벤트의 비트 마스크입니다. data는 불투명 객체입니다.
새 SelectorKey 인스턴스를 반환하거나, 잘못된 이벤트 마스크나 파일 디스크립터의 경우 ValueError를, 파일 객체가 이미 등록된 경우 KeyError를 발생시킵니다.
unregister(fileobj)
선택에서 파일 객체를 등록 해제하여 모니터링에서 제거합니다. 파일 객체는 닫히기 전에 등록 해제되어야 합니다.
fileobj는 이전에 등록된 파일 객체여야 합니다.
연관된 SelectorKey 인스턴스를 반환하거나, fileobj가 등록되지 않았으면 KeyError를 발생시킵니다. fileobj가 유효하지 않으면(예: fileno() 메서드가 없거나 그 반환 값이 잘못된 경우) ValueError를 발생시킵니다.
modify(fileobj, events, data=None)
등록된 파일 객체의 모니터링 이벤트나 첨부 데이터를 변경합니다.
이것은 BaseSelector.unregister(fileobj) 다음에 BaseSelector.register(fileobj, events, data)를 호출하는 것과 같지만 더 효율적으로 구현할 수 있습니다.
새 SelectorKey 인스턴스를 반환하거나, 잘못된 이벤트 마스크나 파일 디스크립터의 경우 ValueError를, 파일 객체가 등록되지 않은 경우 KeyError를 발생시킵니다.
select(timeout=None)
등록된 일부 파일 객체가 준비되거나 타임아웃이 만료될 때까지 기다립니다.
timeout > 0이면 최대 대기 시간(초)을 지정합니다.timeout <= 0이면 호출이 블록되지 않고 현재 준비된 파일 객체를 보고합니다.timeout이None이면 모니터링되는 파일 객체가 준비될 때까지 블록합니다.
각 준비된 파일 객체에 대해 하나씩 (key, events) 튜플 목록을 반환합니다. key는 준비된 파일 객체에 해당하는 SelectorKey 인스턴스이고, events는 이 파일 객체에서 준비된 이벤트의 비트마스크입니다.
Note
현재 프로세스가 시그널을 받으면 어떤 파일 객체도 준비되지 않거나 타임아웃이 경과하기 전에 이 메서드가 반환할 수 있습니다: 이 경우 빈 목록이 반환됩니다.
versionchanged: 3.5에서 셀렉터는 시그널에 의해 중단되고 시그널 핸들러가 예외를 발생시키지 않으면 재계산된 타임아웃으로 재시도됩니다(PEP 475 참고). 이전에는 타임아웃 전에 빈 이벤트 목록을 반환했습니다.
close()
셀렉터를 닫습니다.
기저 리소스가 해제되도록 하려면 반드시 호출해야 합니다. 닫힌 후에는 셀렉터를 사용해서는 안 됩니다.
get_key(fileobj)
등록된 파일 객체와 연관된 키를 반환합니다.
이 파일 객체와 연관된 SelectorKey 인스턴스를 반환하거나, 파일 객체가 등록되지 않았으면 KeyError를 발생시킵니다.
get_map()
파일 객체를 셀렉터 키에 매핑하는 매핑을 반환합니다.
등록된 파일 객체를 그와 연관된 SelectorKey 인스턴스에 매핑하는 Mapping 인스턴스를 반환합니다.
selectors.DefaultSelector
현재 플랫폼에서 사용할 수 있는 가장 효율적인 구현을 사용하는 기본 셀렉터 클래스입니다. 대부분의 사용자에게 기본 선택이어야 합니다.
selectors.SelectSelector
select.select() 기반 셀렉터.
selectors.PollSelector
select.poll() 기반 셀렉터.
selectors.EpollSelector
select.epoll() 기반 셀렉터.
- fileno() — 기저의
select.epoll()객체가 사용하는 파일 디스크립터를 반환합니다.
selectors.DevpollSelector
select.devpoll() 기반 셀렉터.
- fileno() — 기저의
select.devpoll()객체가 사용하는 파일 디스크립터를 반환합니다.
versionadded: 3.5.
selectors.KqueueSelector
select.kqueue() 기반 셀렉터.
- fileno() — 기저의
select.kqueue()객체가 사용하는 파일 디스크립터를 반환합니다.
예제
간단한 에코 서버 구현입니다:
import selectors
import socket
sel = selectors.DefaultSelector()
def accept(sock, mask):
conn, addr = sock.accept() # Should be ready
print('accepted', conn, 'from', addr)
conn.setblocking(False)
sel.register(conn, selectors.EVENT_READ, read)
def read(conn, mask):
data = conn.recv(1000) # Should be ready
if data:
print('echoing', repr(data), 'to', conn)
conn.send(data) # Hope it won't block
else:
print('closing', conn)
sel.unregister(conn)
conn.close()
sock = socket.socket()
sock.bind(('localhost', 1234))
sock.listen(100)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)
while True:
events = sel.select()
for key, mask in events:
callback = key.data
callback(key.fileobj, mask)