Python eventlet
17952 단어 openstack 기초 지식python
이벤트 let 는 python 라 이브 러 리 함수 입 니 다. 하 나 는 네트워크 와 관련 된 처리 이 고 다른 하 나 는 협 정 을 통 해 병행 할 수 있 습 니 다.병발 이란 여러 개의 greenthread (녹색 스 레 드) 를 열 고 이 greenthread 를 관리 하여 비 차단 식 I / O 를 실현 하 는 것 이다.이벤트 let 는 '녹색 스 레 드' 를 실현 하기 위해 python 의 네트워크 와 관련 된 몇 개의 표준 라 이브 러 리 함 수 를 바 꾸 었 고 패 치 (patch) 방식 으로 프로그램 에 가 져 올 수 있 습 니 다. python 의 라 이브 러 리 함 수 는 일반적인 스 레 드 만 지원 하고 협 의 를 지원 하지 않 기 때문에 이벤트 let 는 '녹화' 라 고 부 릅 니 다.
본 고 는 먼저 Greenlet, GreenThread 를 설명 한 다음 에 eventlet 에서 자주 사용 하 는 몇 가지 유형 을 설명 한다.
GreenLet
greenlet 은 협 정 (coroutine) 이 라 고 불 리 는 물건 으로 다음 과 같은 몇 가지 특징 이 있다.1. 모든 협 정 은 자신의 개인 stack 과 부분 변 수 를 가진다.2. 같은 시간 에 하나의 협정 만 운행 되 기 때문에 일부 공유 변수 에 자 물 쇠 를 채 울 필요 가 없다.3. 협 정 간 의 집행 순 서 는 절차 에 의 해 제어 된다.한 마디 로 하면 협 정 은 한 스 레 드 에서 실행 되 는 의사 병행 방식 으로 최종 적 으로 하나의 협 정 만 운행 한 다음 에 프로그램 이 집행 순 서 를 제어 하 는 것 이다.아래 의 예 를 보고 위의 뜻 을 이해 할 수 있다.
import greenlet
def test1(n):
print "test1:",n
gr2.switch(32)
print "test1: over"
def test2(n):
print "test2:",n
gr1.switch(23)
print "test2: over"
greenlet = greenlet.greenlet
current = greenlet.getcurrent()
gr1 = greenlet(test1,current)
gr2 = greenlet(test2,current)
gr1.switch(2)
이 프로그램의 실행 결 과 는 다음 과 같다.
test1: 2
test2: 32
test1: over
전체 프로그램의 과정 은 매우 직 설 적 입 니 다. 먼저 두 개의 협 정 을 만 들 고 생 성 하 는 과정 은 실행 할 함수 와 부모 greenlet (앞에서 제시 한 세 개의 링크 에 상세 한 소개 가 있 습 니 다) 에 들 어간 다음 에 그 중의 한 협 정의 switch 함 수 를 호출 하고 매개 변 수 를 전달 하 며 test 1 을 실행 한 다음 에 gr2. switch (32) 문 구 를 통 해 test 2 함수 로 전환 합 니 다.마지막 에 다시 돌려.최종 test 1 실행 이 끝나 면 부모 greenlet 으로 돌아 가 실행 이 끝 납 니 다.이 과정 은 시종일관 하나의 협정 만 운행 하고 함수 의 집행 흐름 은 프로그램 스스로 제어 하 는 것 이다.이 과정 은 위의 링크 에서 더욱 구체 적 으로 묘사 되 었 다.
참고 자료:http://greenlet.readthedocs.org/en/latest/
GreenThread
그러면 이벤트 let 에서 greenlet 에 대해 간단 한 패 키 징 을 하면 GreenThread 가 되 고 위의 프로그램 에 문제 가 생 길 수 있 습 니 다. 만약 에 우리 가 협 정 을 쓰 려 면 함수 의 집행 과정 을 어떻게 통제 해 야 하 는 지, 협 정 이 많 으 면 통제 가 복잡 하지 않 습 니까?이 문 제 를 가지 고 이벤트 let 의 실현 을 보다.
이벤트 Let 에서 GreenThread 의 스케줄 링 은 hub 를 통 해 이 루어 집 니 다.hub 는 EventLet 의 시간 순환 으로 IO 이벤트 와 GreenThread 를 조정 합 니 다.Hub 는 epolls, poll, selects, pyevent 버 전 등 다양한 버 전의 구현 이 있 습 니 다.http://eventlet.net/doc/hubs.html#eventlet.hubs.use_hub)。이벤트 let. hubs. use 사용 가능hub (hub = None) 는 사용 하 는 hub 를 설정 합 니 다. 그 중에서 들 어 오 는 매개 변 수 는 선택 한 hub 의 이름 입 니 다.
hub 는 스 레 드 국 의 인 스 턴 스 입 니 다. 즉, 모든 스 레 드 에 hub 가 있 습 니 다. 이 스 레 드 의 co - rountine 스케줄 을 관리 하 는 데 사 용 됩 니 다.모든 스 레 드 에 적합 한 hub 를 선택 할 수 있 습 니 다.
hub 작업 원리: hub 는 자체 적 으로 GreenLet 을 가지 고 있 습 니 다. MainLoop 입 니 다. 실행 중인 coroutine 이 IO 작업 이 필요 할 때 이 co - routine 은 hub 에 모니터 를 등록 합 니 다 (hub 는 언제 co - routine wake up 을 알 고 있 습 니 다).다른 실행 가능 한 co - routine 이 있 으 면 hub MainLoop 은 이 co - routine (via get hub (). switch () 로 전환 합 니 다.이 co - routime 이 완성 되 었 거나 IO 가 필요 하 다 면 hub main Loop 으로 전환 합 니 다.이렇게 하면 모든 co - rountine 이 배 치 될 수 있 도록 보장 합 니 다.
hub MAINLOOP 은 첫 번 째 IO 작업 에서 시 작 됩 니 다.이 lazy 모드 는 디 스 패 치 함 수 를 표시 하지 않 아 도 됩 니 다.
이벤트 let 공식 문서 (http://eventlet.net/doc/basic_usage.html)
GreenPool
이 모듈 은 greenthread 풀 에 대한 지원 을 제공 합 니 다.
greenthread 탱크 는 일정한 수량의 예비 greenthread 를 제공 하여 부화 greenthread 가 너무 많아 서 발생 하 는 메모리 부족 을 효과적으로 제한 합 니 다. 연못 에 충분 한 여유 가 없 을 때 부화 과정 이 중단 되 고 이전 작업 중의 greenthread 가 현재 작업 을 완성 해 야 다음 작업 에 부화 준 비 를 할 수 있 습 니 다.
class eventlet. greenpool. GreenPool (size = 1000) 클래스 의 주요 방법: 1. free ()
2. imap(function, *iterables)
3. resize(new_size)
4. running()
5. spawn(function, *args, **kwargs)
6. spawn_n(function, *args, **kwargs)
7. starmap(function, iterable)
8. waitall()
9. waiting () 1. free (): 현재 대상 에서 사용 할 수 있 는 greenthreads 를 되 돌려 줍 니 다.
0 또는 더 적 으 면 spawn () 과 spawnn () 은 새로운 사용 가능 한 greenthread 가 있 을 때 까지 greenthread 호출 을 막 을 것 입 니 다.
이 곳 에서 마이너스 값 을 되 돌 릴 수 있 는 이 유 는 3. resize () 2. imap (function, * iterables) 를 보십시오. 효 과 는 itertools. imap () 와 같 고 병발 과 메모리 사용 에 있어 서 starmap () 과 같 습 니 다.
예 를 들 어 파일 에 대해 매우 편리 하 게 조작 할 수 있다.
def worker(line):
return do_something(line)
pool = GreenPool()
for result in pool.imap(worker, open("filename", 'r')):
print(result)
GreenPile
class eventlet. greenpool. GreenPile (size or pool = 1000) 는 내부 에서 GreenPool 대상 과 Queue 대상 을 유지 합 니 다.이 GreenPool 대상 은 외부 에서 전 달 될 수도 있 고 클래스 내부 에서 만 들 수도 있 습 니 다. GreenPool 대상 은 주로 녹색 스 레 드 를 만 드 는 데 사 용 됩 니 다. 즉, GreenPile 내부 에서 Greenpool. spawn () 방법 을 호출 했 습 니 다.Queue 대상 은 spawn () 방법의 반환 값 을 유지 하 는 데 사 용 됩 니 다. 즉, Queue 에 저 장 된 것 은 GreenThread 대상 입 니 다.또한 next () 방법 도 실현 했다 는 것 은 GreenPile 대상 이 교체 기의 성질 을 가지 고 있다 는 것 을 의미한다.그래서 만약 에 우리 가 녹색 스 레 드 의 반환 값 을 조작 하려 면 이런 종 류 를 사용 하 는 것 이 더 할 나 위 없 이 좋다.
Event
class eventlet. event. Event Event: 같은 라인 에서 의 협정 통신 메커니즘 (an arbitrary number of coroutines can wait for one event from another).Event 와 Queue 형식 은 하나의 메시지 만 수용 할 수 있 는 Queue 로 볼 수 있 습 니 다. 그러나 Queue 와 다른 것 은: (1) send () 를 호출 하면 현재 greenthread 에 대한 예약 을 취소 하지 않 습 니 다.(2) 이벤트 인 스 턴 스 에 대해 send 함 수 를 한 번 만 호출 할 수 있 습 니 다.만약 당신 이 두 개의 메 시 지 를 보 낼 필요 가 있다 면, 두 개의 이벤트 대상 이 필요 합 니 다.사용 실례:
from eventlet import event
import eventlet
evt = event.Event()
def baz(b):
evt.send(b + 1)
_ = eventlet.spawn_n(baz, 3)
evt.wait()
함수 설명: 1. ready (): 이벤트 대상 이 이 벤트 를 보 낸 적 이 있 는 지 판단 합 니 다. wait () 를 호출 하면 이벤트 결 과 를 즉시 되 돌려 줍 니 다. 그러면 이 곳 에서 실제 값 을 되 돌려 줍 니 다.그 방법 은 한동안 기 다 려 야 발생 하 는 사건 을 피 하 는 데 쓰 인 다.예 를 들 어 하나의 이벤트 들 을 Python 목록 에 넣 고 반복 해서 옮 겨 다 닐 수 있 습 니 다. 이것 은 ready () 를 사용 하여 하나의 이벤트 가 True 로 돌아 갈 때 까지 즉시 wait () 를 호출 하여 가 져 올 수 있 습 니 다.2. send (result = None, exc = None): 이 벤트 를 보 내 면 다른 wait 의 협 정 을 깨 울 수 있 습 니 다.이 방법 을 호출 하 는 협 정 은 즉시 돌아 갑 니 다 (막 히 지 않 습 니 다)
>>> from eventlet import event
>>> import eventlet
>>> evt = event.Event()
>>> def waiter():
... print('about to wait')
... result = evt.wait()
... print('waited for {0}'.format(result))
>>> _ = eventlet.spawn(waiter)
>>> eventlet.sleep(0)
about to wait
>>> evt.send('a')
>>> eventlet.sleep(0)
waited for a
주의해 야 할 것 은 같은 이벤트 인 스 턴 스 에 여러 번 send 함 수 를 호출 하면 이상 을 던 질 수 있 습 니 다.
>>> evt.send('whoops')
Traceback (most recent call last):
...
AssertionError: Trying to re-send() an already-triggered event.
>>> from eventlet import event
>>> evt = event.Event()
>>> evt.send_exception(RuntimeError())
>>> evt.wait()
Traceback (most recent call last):
File "" , line 1, in <module>
File "eventlet/event.py", line 120, in wait
current.throw(*self._exc)
RuntimeError
스 택 궤적 을 완전 하 게 유지 하려 면 sys. exc 전체 에 전송 해 야 합 니 다.info () 모듈.
>>> import sys
>>> evt = event.Event()
>>> try:
... raise RuntimeError()
... except RuntimeError:
... evt.send_exception(*sys.exc_info())
...
>>> evt.wait()
Traceback (most recent call last):
File "" , line 1, in
File "eventlet/event.py", line 120, in wait
current.throw(*self._exc)
File "" , line 2, in
RuntimeError
이벤트 대상 내부 에 traceback 대상 을 저장 합 니 다. 이 는 순환 참조 로 이 어 질 수 있 습 니 다.sys. exc 참조info () 문서 입 니 다.
>>> from eventlet import event
>>> import eventlet
>>> evt = event.Event()
>>> def wait_on():
... retval = evt.wait()
... print("waited for {0}".format(retval))
>>> _ = eventlet.spawn(wait_on)
>>> evt.send('result')
>>> eventlet.sleep(0)
waited for result
참고:http://eventlet.net/doc/modules/event.html http://www.cnblogs.com/Security-Darren/p/4168116.html
예 를 들다
1. 인터넷 파충류, 녹색 스 레 드 탱크 로 urls 의 정 보 를 얻 습 니 다.녹색 스 레 드 탱크 와 imap () 함 수 를 사용 합 니 다.
import eventlet
from eventlet.green import urllib2
urls = [
"http://www.google.com/intl/en_ALL/images/logo.gif",
"https://wiki.secondlife.com/w/images/secondlife.jpg",
"http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif",
]
def fetch(url):
return urllib2.urlopen(url).read()
pool = eventlet.GreenPool(200) # ,
for body in pool.imap(fetch, urls): # url
print("got body", len(body))
2, socket 서버
import eventlet
def handle(fd):
print "client connected"
while True: #
# pass through every non-eof line
x = fd.readline()
if not x: break
fd.write(x)
fd.flush() #
print "echoed", x,
print "client disconnected"
print "server socket listening on port 8000" # ,
server = eventlet.listen(('127.0.0.1', 8000)) # (IP , )
pool = eventlet.GreenPool(200) # ,
while True:
new_sock, address = server.accept() # , socket IP
print "accepted", address
pool.spawn_n(handle, new_sock.makefile('rw')) #
3. GreenPile 을 사용 한 예
import eventlet
from eventlet.green import socket
def geturl(url):
c = socket.socket()
ip = socket.gethostbyname(url)
c.connect((ip, 80))
print '%s connected' % url
c.sendall('GET /\r
\r
')
return c.recv(1024)
urls = ['www.google.com', 'www.yandex.ru', 'www.python.org']
pile = eventlet.GreenPile()
for x in urls:
pile.spawn(geturl, x)
# note that the pile acts as a collection of return values from the functions
# if any exceptions are raised by the function they'll get raised here
for url, result in zip(urls, pile):
print '%s: %s' % (url, repr(result)[:50])
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
파이썬을 사용하여 10진수를 bin, 8진수 및 16진수 형식으로 변환하는 방법은 무엇입니까?텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.