python 의 select 모듈 을 깊이 이해 합 니 다.
Python 의 select 모듈 은 I/O 다 중 재 활용 에 전념 하여 select 를 제공 합 니 다. poll epoll 세 가지 방법(그 중 두 가 지 는 Linux 에서 사용 할 수 있 고 windows 는 select 만 지원 합 니 다),또한 kquue 방법(freeBSD 시스템)도 제공 합 니 다.
select 방법
프로 세 스 는 커 널 이 어떤 파일 설명자(최대 1024 개 fd 감청)를 감청 하 는 지 지정 합 니 다.파일 설명자 사건 이 발생 하지 않 았 을 때 프로 세 스 가 막 혔 습 니 다.하나 이상 의 파일 설명자 이벤트 가 발생 했 을 때 프로 세 스 가 깨 어 났 습 니 다.
우리 가 select()를 호출 할 때:
1.문맥 이 커 널 상태 로 전환
2.fd 를 사용자 공간 에서 커 널 공간 으로 복사 합 니 다.
3.커 널 은 모든 fd 를 옮 겨 다 니 며 해당 이벤트 가 발생 했 는 지 확인 합 니 다.
4.발생 하지 않 으 면 프로 세 스 를 막 습 니 다.장치 구동 이 중단 되 거나 timeout 시간 이 발생 하면 프로 세 스 를 깨 우 고 다시 옮 겨 다 닙 니 다.
5.옮 겨 다 니 는 fd 를 되 돌려 줍 니 다.
6.fd 를 커 널 공간 에서 사용자 공간 으로 복사 합 니 다.
fd:파일 기술자 파일 설명자
fd_r_list, fd_w_list, fd_e_list = select.select(rlist, wlist, xlist, [timeout])
매개 변수:네 개의 매개 변 수 를 받 아들 일 수 있 습 니 다(앞의 세 개 는 필수)select 방법 은 파일 설명자(파일 설명자 조건 이 만족 하지 않 을 때 select 가 막 힙 니 다)를 감시 하 는 데 사 용 됩 니 다.파일 설명자 상태 가 바 뀌 면 세 개의 목록 을 되 돌려 줍 니 다.
1.매개 변수 1 시퀀스 의 fd 가'읽 기 가능'조건 을 만족 시 킬 때 변화 하 는 fd 를 가 져 와 fd 에 추가 합 니 다.r_목록
2.매개 변수 2 시퀀스 에 fd 가 포함 되 어 있 을 때 이 시퀀스 의 모든 fd 를 fd 에 추가 합 니 다.w_목록
3.매개 변수 3 시퀀스 의 fd 에 오류 가 발생 하면 이 오류 가 발생 한 fd 를 fd 에 추가 합 니 다.e_목록
4.시간 초과 시간 이 비어 있 으 면 select 는 감청 의 핸들 이 변 할 때 까지 계속 차단 합 니 다.
시간 초과=n(정수)일 때 감청 핸들 이 변 하지 않 으 면 selection 은 n 초 를 막 고 세 개의 빈 목록 으로 돌아 가 감청 핸들 이 변 하면 바로 실 행 됩 니 다.
인 스 턴 스:select 를 이용 하여 동시 다발 가능 한 서버 를 실현 합 니 다.
import socket
import select
s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
r_list = [s,]
num = 0
while True:
rl, wl, error = select.select(r_list,[],[],10)
num+=1
print('counts is %s'%num)
print("rl's length is %s"%len(rl))
for fd in rl:
if fd == s:
conn, addr = fd.accept()
r_list.append(conn)
msg = conn.recv(200)
conn.sendall(('first----%s'%conn.fileno()).encode())
else:
try:
msg = fd.recv(200)
fd.sendall('second'.encode())
except ConnectionAbortedError:
r_list.remove(fd)
s.close()
import socket
flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
input_msg = input('input>>>')
if input_msg == '0':
break
s.sendall(input_msg.encode())
msg = s.recv(1024)
print(msg.decode())
s.close()
서버 에서 우 리 는 select 를 끊임없이 호출 해 야 한 다 는 것 을 알 수 있 습 니 다.이것 은 다음 과 같 습 니 다.1 파일 설명자 가 너무 많 을 때 파일 설명자 가 사용자 공간 과 커 널 공간 에서 copy 를 하 는 데 시간 이 많이 걸 립 니 다.
2 파일 설명자 가 너무 많 을 때 커 널 이 파일 설명자 에 대한 옮 겨 다 니 는 것 도 시간 을 낭비 합 니 다.
3 select 최대 1024 개의 파일 설명자 만 지원 합 니 다.
poll 과 select 의 차이 가 크 지 않 으 므 로 본 고 는 소개 하지 않 습 니 다.
epoll 방법:
epoll 은 select 를 잘 개선 했다.
1.epoll 의 해결 방안 은 epoll 에 있 습 니 다.ctl 함수 중.epoll 핸들 에 새로운 이 벤트 를 등록 할 때마다 epoll 이 아 닌 모든 fd 를 커 널 에 복사 합 니 다.wait 때 복사 반복.epoll 은 모든 fd 가 전체 과정 에서 한 번 만 복사 할 수 있 도록 보장 합 니 다.
2,epoll 은 epollctl 시 지정 한 fd 를 한 번 옮 겨 다 니 며(이번 에는 없어 서 는 안 됩 니 다)모든 fd 에 리 셋 함 수 를 지정 합 니 다.장치 가 준비 되 어 대기 열 에 있 는 대기 자 를 깨 울 때 이 리 셋 함 수 를 호출 합 니 다.이 리 셋 함 수 는 준 비 된 fd 를 준비 링크 에 추가 합 니 다.epoll_wait 작업 은 실제로 이 준비 링크 에서 준비 되 어 있 는 fd 를 확인 하 는 것 입 니 다.
3.epoll 은 파일 설명자 에 대해 추가 제한 이 없습니다.
select.epoll(sizehint=-1, flags=0) epoll
epoll.close()
Close the control file descriptor of the epoll object. epoll
epoll.closed
True if the epoll object is closed. epoll
epoll.fileno()
Return the file descriptor number of the control fd. epoll
epoll.fromfd(fd)
Create an epoll object from a given file descriptor. fd epoll
epoll.register(fd[, eventmask])
Register a fd descriptor with the epoll object. epoll fd
epoll.modify(fd, eventmask)
Modify a registered file descriptor. fd
epoll.unregister(fd)
Remove a registered file descriptor from the epoll object.
epoll.poll(timeout=-1, maxevents=-1)
Wait for events. timeout in seconds (float) , fd , dict, :{(fd1,event1),(fd2,event2),……(fdn,eventn)}
이벤트:
EPOLLIN Available for read 1
EPOLLOUT Available for write 4
EPOLLPRI Urgent data for read
EPOLLERR Error condition happened on the assoc. fd 8
EPOLLHUP Hang up happened on the assoc. fd
EPOLLET Set Edge Trigger behavior, the default is Level Trigger behavior ,
EPOLLONESHOT Set one-shot behavior. After one event is pulled out, the fd is internally disabled
EPOLLRDNORM Equivalent to EPOLLIN
EPOLLRDBAND Priority data band can be read.
EPOLLWRNORM Equivalent to EPOLLOUT
EPOLLWRBAND Priority data may be written.
EPOLLMSG Ignored.
수평 트리거 와 가장자리 트리거:Level_triggered(수평 트리거,조건 트리거 라 고도 함):감 시 된 파일 설명자 에 읽 기와 쓰기 이벤트 가 발생 했 을 때
epoll.poll()
처리 프로그램 에 읽 기와 쓰 기 를 알 립 니 다.만약 이번에 데 이 터 를 한꺼번에 다 읽 고 쓰 지 않 았 다 면(예 를 들 어 읽 기 쓰기 버퍼 가 너무 작 았 다 면)다음 호출epoll.poll()
에 서 는 다 읽 지 못 한 파일 설명자 에서 계속 읽 고 쓰 라 고 알려 줄 것 입 니 다.물론 읽 고 쓰 지 않 으 면 계속 알려 줄 것 입 니 다!!만약 시스템 에 읽 고 쓸 필요 가 없 는 준 비 된 파일 설명자 가 대량으로 있다 면,그들 은 매번 돌아 올 것 입 니 다.그러면 처리 프로그램 이 자신 이 관심 을 가 지 는 준 비 된 파일 설명 자 를 검색 하 는 효율 을 크게 낮 출 것 입 니 다!!장점 뚜렷:안정 적 이 고 신뢰 할 수 있다.Edge_triggered(가장자리 트리거,상태 트리거 라 고도 함):감 시 된 파일 설명자 에 읽 기와 쓰기 이벤트 가 발생 했 을 때
epoll.poll()
처리 프로그램 에 읽 기와 쓰 기 를 알 립 니 다.만약 이번에 데 이 터 를 전부 읽 고 쓰 지 않 았 다 면(예 를 들 어 읽 기 쓰기 버퍼 가 너무 작 았 다 면)다음 호출epoll.poll()
시 알려 주지 않 을 것 입 니 다.즉,이 파일 설명자 에 두 번 째 읽 기 쓰기 이벤트 가 나타 날 때 까지 한 번 만 알려 줄 것 입 니 다!!이러한 모델 은 수평 트리거 효율 보다 높 습 니 다.시스템 은 당신 이 관심 이 없 는 준비 파일 설명자 로 가득 하지 않 습 니 다!!단점:어떤 조건 에 서 는 믿 을 수 없다.epoll 실례:
import socket
import select
s = socket.socket()
s.bind(('127.0.0.1',8888))
s.listen(5)
epoll_obj = select.epoll()
epoll_obj.register(s,select.EPOLLIN)
connections = {}
while True:
events = epoll_obj.poll()
for fd, event in events:
print(fd,event)
if fd == s.fileno():
conn, addr = s.accept()
connections[conn.fileno()] = conn
epoll_obj.register(conn,select.EPOLLIN)
msg = conn.recv(200)
conn.sendall('ok'.encode())
else:
try:
fd_obj = connections[fd]
msg = fd_obj.recv(200)
fd_obj.sendall('ok'.encode())
except BrokenPipeError:
epoll_obj.unregister(fd)
connections[fd].close()
del connections[fd]
s.close()
epoll_obj.close()
import socket
flag = 1
s = socket.socket()
s.connect(('127.0.0.1',8888))
while flag:
input_msg = input('input>>>')
if input_msg == '0':
break
s.sendall(input_msg.encode())
msg = s.recv(1024)
print(msg.decode())
s.close()
총결산이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
로마 숫자를 정수로 또는 그 반대로 변환그 중 하나는 로마 숫자를 정수로 변환하는 함수를 만드는 것이었고 두 번째는 그 반대를 수행하는 함수를 만드는 것이었습니다. 문자만 포함합니다'I', 'V', 'X', 'L', 'C', 'D', 'M' ; 문자열이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.