Python 비동기 IO 구현 예시
블록 API 로 동기 화 코드 를 쓰 는 것 이 가장 간단 하지만 하나의 스 레 드 는 같은 시간 에 하나의 요청 만 처리 할 수 있 습 니 다.제 한 된 스 레 드 수 로 인해 만 단계 의 병렬 연결 을 실현 하지 못 하고 너무 많은 스 레 드 전환 도 CPU 의 시간 을 빼 앗 아 초당 처리 할 수 있 는 요청 수량 을 낮 출 수 있 습 니 다.높 은 병발 을 위해 비동기 프레임 워 크 를 선택 할 수 있 습 니 다.비 차단 API 로 업무 논 리 를 여러 개의 반전 함수 로 흐 트 러 뜨리 고 다 중 재 활용 과 이벤트 순환 방식 으로 높 은 병발 을 실현 할 수 있 습 니 다.
디스크 IO 의 경우 다 중 스 레 드 에서 차단 방법 으로 디스크 를 읽 고 2 개의 스 레 드 간 전환 방식 을 설명 합 니 다.그렇다면 어떻게 해야만 높 은 병발 을 실현 할 수 있 을 까?
위의 그림 에서 커 널 에서 실 현 된 요청 전환 작업 을 사용자 상태의 코드 에 맡 기 면 됩 니 다.비동기 화 프로 그래 밍 은 응용 층 코드 를 통 해 요청 전환 을 실현 하고 전환 원가 와 메모리 점용 공간 을 낮 춥 니 다.비동기 화 는 IO 다 중 재 활용 체제 에 의존 합 니 다.예 를 들 어 Linux 의 epoll 이나 Windows 의 iocp 등 이 있 습 니 다.또한 차단 방법 을 비 차단 방법 으로 바 꿔 야 커 널 전환 에 따 른 큰 소 모 를 피 할 수 있 습 니 다.Nginx,Redis 등 고성능 서 비 스 는 모두 비동기 화 에 의존 해 백만 급 의 병발 을 이 루 었 다.
다음 그림 은 비동기 IO 의 비 차단 읽 기와 비동기 프레임 워 크 가 결 합 된 후 요청 을 어떻게 전환 하 는 지 설명 한다.
그러나 비동기 화 코드 를 쓰 는 것 은 오류 가 발생 하기 쉽다.모든 차단 함 수 는 차단 되 지 않 은 시스템 호출 을 통 해 두 함수 로 나 누 어야 하기 때문이다.이 두 함수 가 공동으로 하나의 기능 을 완성 하지만 호출 방식 은 다르다.첫 번 째 함 수 는 당신 이 명시 적 으로 호출 하고 두 번 째 함 수 는 다 중 재 활용 체제 에서 호출 합 니 다.
이런 방식 은 소프트웨어 공학 의 내부 집적 원칙 을 위반 하고 함수 간 동기 데이터 도 더욱 복잡 하 다.특히 조건 이 많 고 대량의 시스템 호출 과 관련 될 때 비동기 화 된 개조 작업 은 매우 어 려 울 것 이다.
Python 은 어떻게 비동기 호출 을 실현 합 니까?
from flask import Flask
import time
app = Flask(__name__)
@app.route('/bar')
def bar():
time.sleep(1)
return '<h1>bar!</h1>'
@app.route('/foo')
def foo():
time.sleep(1)
return '<h1>foo!</h1>'
if __name__ == '__main__':
app.run(host='127.0.0.1',port=5555,debug=True)
동기 화 방식 으로 호출 하 다
import requests
import time
starttime = time.time()
print(requests.get('http://127.0.0.1:5555/bar').content)
print(requests.get('http://127.0.0.1:5555/foo').content)
print(" : ",time.time() -starttime)
b'bar!'
b'foo!'
소모 시간: 2.015509605407715
샘플링 비동기 방식 호출:
중점:
1.차단 io 를 비 차단 io 로 변경 합 니 다.
2.다 중 재 활용 io 커 널 이벤트 감청,이벤트 트리거 는 리 셋 함 수 를 통 해 발생 합 니 다.
3.사용자 상태 코드 는 이벤트 순환 방식 으로 이 벤트 를 가 져 오고 이벤트 의 리 셋 함 수 를 실행 합 니 다.
import selectors
import socket
import time
# from asynrequest import ParserHttp
class asynhttp:
def __init__(self):
self.selecter = selectors.DefaultSelector()
def get(self,url,optiondict = None):
global reqcount
reqcount += 1
s = socket.socket()
s.setblocking(False)
try:
s.connect(('127.0.0.1',5555))
except BlockingIOError:
pass
requset = 'GET %s HTTP/1.0\r
\r
' % url
callback = lambda : self.send(s,requset)
self.selecter.register(s.fileno(),selectors.EVENT_WRITE,callback)
def send(self,s,requset):
self.selecter.unregister(s.fileno())
s.send(requset.encode())
chunks = []
callback = lambda: self.recv(s,chunks)
self.selecter.register(s.fileno(),selectors.EVENT_READ,callback)
def recv(self,s,chunks):
self.selecter.unregister(s.fileno())
chunk = s.recv(1024)
if chunk:
chunks.append(chunk)
callback = lambda: self.recv(s,chunks)
self.selecter.register(s.fileno(), selectors.EVENT_READ, callback)
else:
global reqcount
reqcount -= 1
request_first,request_headers,request_content,_ = ParserHttp.parser(b''.join(chunks))
print(" :",request_first,request_headers,request_content)
print((b''.join(chunks)).decode())
return (b''.join(chunks)).decode()
starttime = time.time()
reqcount = 0
asynhttper = asynhttp()
asynhttper.get('/bar')
asynhttper.get('/foo')
while reqcount:
events = asynhttper.selecter.select()
for event,mask in events:
func = event.data
func()
print(" :" ,time.time() - starttime)
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT
bar!
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT
foo!
소모 시간:1.012763738632121
이상 은 Python 이 비동기 IO 를 실현 하 는 예제 의 상세 한 내용 입 니 다.python 비동기 IO 에 관 한 자 료 는 다른 관련 글 에 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.
소모 시간: 2.015509605407715
샘플링 비동기 방식 호출:
중점:
1.차단 io 를 비 차단 io 로 변경 합 니 다.
2.다 중 재 활용 io 커 널 이벤트 감청,이벤트 트리거 는 리 셋 함 수 를 통 해 발생 합 니 다.
3.사용자 상태 코드 는 이벤트 순환 방식 으로 이 벤트 를 가 져 오고 이벤트 의 리 셋 함 수 를 실행 합 니 다.
import selectors
import socket
import time
# from asynrequest import ParserHttp
class asynhttp:
def __init__(self):
self.selecter = selectors.DefaultSelector()
def get(self,url,optiondict = None):
global reqcount
reqcount += 1
s = socket.socket()
s.setblocking(False)
try:
s.connect(('127.0.0.1',5555))
except BlockingIOError:
pass
requset = 'GET %s HTTP/1.0\r
\r
' % url
callback = lambda : self.send(s,requset)
self.selecter.register(s.fileno(),selectors.EVENT_WRITE,callback)
def send(self,s,requset):
self.selecter.unregister(s.fileno())
s.send(requset.encode())
chunks = []
callback = lambda: self.recv(s,chunks)
self.selecter.register(s.fileno(),selectors.EVENT_READ,callback)
def recv(self,s,chunks):
self.selecter.unregister(s.fileno())
chunk = s.recv(1024)
if chunk:
chunks.append(chunk)
callback = lambda: self.recv(s,chunks)
self.selecter.register(s.fileno(), selectors.EVENT_READ, callback)
else:
global reqcount
reqcount -= 1
request_first,request_headers,request_content,_ = ParserHttp.parser(b''.join(chunks))
print(" :",request_first,request_headers,request_content)
print((b''.join(chunks)).decode())
return (b''.join(chunks)).decode()
starttime = time.time()
reqcount = 0
asynhttper = asynhttp()
asynhttper.get('/bar')
asynhttper.get('/foo')
while reqcount:
events = asynhttper.selecter.select()
for event,mask in events:
func = event.data
func()
print(" :" ,time.time() - starttime)
HTTP/1.0 200 OKContent-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT
bar!
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 13
Server: Werkzeug/1.0.1 Python/3.7.7
Date: Thu, 15 Oct 2020 03:28:16 GMT
foo!
소모 시간:1.012763738632121
이상 은 Python 이 비동기 IO 를 실현 하 는 예제 의 상세 한 내용 입 니 다.python 비동기 IO 에 관 한 자 료 는 다른 관련 글 에 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.
소모 시간:1.012763738632121
이상 은 Python 이 비동기 IO 를 실현 하 는 예제 의 상세 한 내용 입 니 다.python 비동기 IO 에 관 한 자 료 는 다른 관련 글 에 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.