Python 에서 gevent 모듈 조정 사용

6925 단어 Pythongevent협정
배경
Python 스 레 드 의 성능 문제 로 인해 Python 에서 다 중 스 레 드 실행 코드 를 사용 하면 예상 한 효 과 를 얻 지 못 합 니 다.실제 개발 에서 우 리 는 항상 높 은 병행 수요 가 있 기 때문에 우리 의 코드 가 더 빨리 달 리 는 동시에 단위 시간 내 에 더 많은 효과 적 인 논 리 를 집행 하고 쓸데없는 기다 림 을 줄 여야 한다.
협 정 이란 무엇 입 니까?
우 리 는 스 레 드 가 경량급 의 프로 세 스 라 고 생각 할 수 있 기 때문에 협 정 이 경량급 의 스 레 드 라 는 것 도 이해 할 수 있다.협 정 은 한 스 레 드 에서 A 함 수 를 실행 할 때 B 함 수 를 수시로 중단 하고 자 유 롭 게 전환 할 수 있 습 니 다.그러나 이 과정 은 함수 호출 이 아니 라 현상 은 다 중 스 레 드 와 마찬가지 로 실제 적 으로 하나의 스 레 드 입 니 다.그 중에서 gevent 는 Python 협 정의 대표 적 인 실현 이다.
gevent 가 뭐 예요?
gevent 는 Python 의 병발 프레임 워 크 로 greenlet 을 바탕 으로 epoll 사건 감청 체제 와 여러 가지 최적화 로 효율 적 입 니 다.그 기본 적 인 사상 은 바로 greenlet 이 하나의 협정 이다.greenlet 이 IO 작업 을 만 났 을 때 예 를 들 어 네트워크 를 방문 하면 자동 으로 다른 greenlet 으로 전환 되 고 IO 가 완성 되면 다시 전환 되 어 계속 집행 된다.gevent 는 우리 가 이 협 정 전환 과정 을 자동 으로 실현 하 는 것 을 도 울 수 있다.
협정 의 예
코드:

import gevent,time

def f1():
    for i in range(5):
        print('function:@@@f1 | NUM: @@@',i)

        #     ,gevent            ↓
        gevent.sleep(0)

def f2():
    for i in range(5):
        print('function:@@@f2 | NUM: @@@',i)

        #     ,gevent            ↑
        gevent.sleep(0)

#         ,         
xc1=gevent.spawn(f1)
xc2=gevent.spawn(f2)

#       gevent   
gevent.joinall([xc1,xc2])
실행 결과:
function:@@@f1 | NUM: @@@ 0
function:@@@f2 | NUM: @@@ 0
function:@@@f1 | NUM: @@@ 1
function:@@@f2 | NUM: @@@ 1
function:@@@f1 | NUM: @@@ 2
function:@@@f2 | NUM: @@@ 2
function:@@@f1 | NUM: @@@ 3
function:@@@f2 | NUM: @@@ 3
function:@@@f1 | NUM: @@@ 4
function:@@@f2 | NUM: @@@ 4
위 와 같이 gevent 가 두 개의 협 정 을 수행 할 때 먼저 xc1 이 gevent.sleep(0)로 실 행 될 때 차단 이 발생 합 니 다.이때 gevent 는 xc2 로 전환 하고 xc2 가 gevent.sleep(0)로 실 행 될 때 차단 이 발생 합 니 다.이때 gevent 는 xc1 로 전환 하여 실행 합 니 다.
Q&A
Q:gevent 에서 캡 처 할 수 없 는 시간 소모
코드:

import gevent,time

def f1():
    for i in range(5):
        print('function:@@@f1 | NUM: @@@',i)

        #     
        time.sleep(0.1)

def f2():
    for i in range(5):
        print('function:@@@f2 | NUM: @@@',i)

        #     
        time.sleep(0.1)

#         ,         
xc1=gevent.spawn(f1)
xc2=gevent.spawn(f2)

#       gevent   
gevent.joinall([xc1,xc2])

실행 결과:
function:@@@f1 | NUM: @@@ 0
function:@@@f1 | NUM: @@@ 1
function:@@@f1 | NUM: @@@ 2
function:@@@f1 | NUM: @@@ 3
function:@@@f1 | NUM: @@@ 4
function:@@@f2 | NUM: @@@ 0
function:@@@f2 | NUM: @@@ 1
function:@@@f2 | NUM: @@@ 2
function:@@@f2 | NUM: @@@ 3
function:@@@f2 | NUM: @@@ 4
위 와 같이 time.sleep(0.1)에 걸 리 는 시간 을 발견 할 수 있 습 니 다.gevent 는 포착 할 수 없 기 때문에 코드 가 직렬 로 되 어 있 습 니 다.비록 우 리 는 협 정 을 만 들 었 지만 다른 역할 을 하지 않 았 습 니 다.
어 떡 하지?아래 의 해결 방안 을 보십시오.
A:원숭이 패 치
포획 할 수 없 는 시간 에 대해 gevent 는 우리 에 게 원숭이 패 치 를 제공 합 니 다.우리 프로그램 에 원숭이 패 치 를 해 주 었 을 때 우리 프로그램 이 시간 이 걸 리 는 조작 을 만 났 을 때 gevent 는 자동 으로 협 정 을 전환 시 켜 비동기 적 인 병행 을 실현 합 니 다.
코드:

import gevent,time
from gevent import monkey;monkey.patch_all()

def f1():
    for i in range(5):
        print('function:@@@f1 | NUM: @@@',i)

        #     
        time.sleep(0.1)

def f2():
    for i in range(5):
        print('function:@@@f2 | NUM: @@@',i)

        #     
        time.sleep(0.1)

#         ,         
xc1=gevent.spawn(f1)
xc2=gevent.spawn(f2)

#       gevent   
gevent.joinall([xc1,xc2])
실행 결과:
function:@@@f1 | NUM: @@@ 0
function:@@@f2 | NUM: @@@ 0
function:@@@f1 | NUM: @@@ 1
function:@@@f2 | NUM: @@@ 1
function:@@@f1 | NUM: @@@ 2
function:@@@f2 | NUM: @@@ 2
function:@@@f1 | NUM: @@@ 3
function:@@@f2 | NUM: @@@ 3
function:@@@f1 | NUM: @@@ 4
function:@@@f2 | NUM: @@@ 4
위 와 같이 협 정의 전환 이 이미 실현 되 었 고 문 제 는 완벽 하 게 해결 되 었 다 는 것 을 알 게 될 것 이다.
실천 하 다.
비동기 요청
코드:

from gevent import monkey;monkey.patch_all()
import gevent,time,requests
from urllib3 import disable_warnings

disable_warnings()

def req(url):
    res = requests.get(url,verify=False)
    if res:
        print('URL:{} | CODE:{}!'.format(url,res.status_code))
    else:
        print('URL:{} FAILED!')

xc1=gevent.spawn(req,'https://www.baidu.com')
xc2=gevent.spawn(req,'https://www.gitee.com')
xc3=gevent.spawn(req,'https://www.huaweicloud.com')

gevent.joinall([xc1,xc2,xc3])

실행 결과:
URL:https://www.baidu.com | CODE:200!
URL:https://www.huaweicloud.com | CODE:200!
URL:https://www.gitee.com | CODE:200!
gevent 의 자물쇠
코드:

from gevent import monkey;monkey.patch_all()
from gevent.lock import Semaphore
import gevent,time

#       1
s1=Semaphore(1)

def f1():
    for i in range(5):
        #    -1,    
        s1.acquire()
        print('function:@@@f1 | NUM: @@@',i)

        #    +1,    
        s1.release()

        #           
        time.sleep(0.1)

def f2():
    for i in range(5):
        #    -1,    
        s1.acquire()
        print('function:@@@f2 | NUM: @@@',i)

        #    +1,    
        s1.release()

        #           
        time.sleep(0.3)

#         ,         
xc1=gevent.spawn(f1)
xc2=gevent.spawn(f2)

#       gevent   
gevent.joinall([xc1,xc2])

실행 결과:
function:@@@f1 | NUM: @@@ 0
function:@@@f2 | NUM: @@@ 0
function:@@@f1 | NUM: @@@ 1
function:@@@f1 | NUM: @@@ 2
function:@@@f2 | NUM: @@@ 1
function:@@@f1 | NUM: @@@ 3
function:@@@f1 | NUM: @@@ 4
function:@@@f2 | NUM: @@@ 2
function:@@@f2 | NUM: @@@ 3
function:@@@f2 | NUM: @@@ 4
위 와 같이 gevent 는 자동 으로 자물쇠 와 차단 을 처리 할 수 있 습 니 다.차단 규칙 에 따라 f1 과 f2 는 교체 하여 실행 되 지만 차단 시간 을 더 합 니 다.f2 의 차단 시간 은 f1 의 3 배 이기 때문에 앞의 6 개의 인쇄 에서 f1 이 실행 하 는 횟수 는 f2 의 3 배 입 니 다.즉,gevent 는 차단 과 잠 금 이 동시에 존재 하 는 상황 을 자동 으로 판단 하고 처리 할 수 있 습 니 다.
Tip
HTTP 의 비동기 개발 에서 원숭이 패 치 는 gevent 를 가 져 오기 전에 해 야 합 니 다.그렇지 않 으 면 이상 이 발생 할 수 있 습 니 다.
파 이 썬 에서 gevent 모듈 프로 세 스에 사용 되 는 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 파 이 썬 gevent 프로 세 스 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

좋은 웹페이지 즐겨찾기