Математические модели нормального поведения сетевых приложений в ПКС сетях
Разработка сетевых приложений с gevent
-
Upload
andrey-popp -
Category
Education
-
view
11.132 -
download
6
description
Transcript of Разработка сетевых приложений с gevent
![Page 1: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/1.jpg)
Разработка сетевых приложений с gevent
Андрей Попп
http://braintrace.ru
@andreypopp
![Page 2: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/2.jpg)
Сетевые сервисы должны уметь одновременно обрабатыватьнесколько клиентских запросов.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 3: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/3.jpg)
Современные сетевые сервисы должны уметь одновременнообрабатывать огромное количество клиентских запросов.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 4: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/4.jpg)
Стратегии организации I/O
Основные стратегии обработки соединений относительноорганизации I/O:
Блокирующий I/O – необходимо несколько потоков ОС.Неблокирующий I/O + мултиплексор – достаточно дажеодного потока ОС.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 5: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/5.jpg)
Блокирующий I/O
Необходимо использовать отдельный поток на каждоеактивное соединение.Много активных соединений = много активных потоков =большое количество потребляемой памяти.Переключение контекста исполнения обходится дорого.В Python есть GIL.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 6: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/6.jpg)
Блокирующий I/O
Объективно не подходит для обслуживания большогоколичество одновременных соединений.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 7: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/7.jpg)
Неблокирующий I/O
Операции на сокетах не блокируют поток – онипроизводяться только тогда, когда доступны.Для обслуживания нескольких активных соединенийдостаточно даже одного потока.Меньшее количество потребляемой памяти.Обычно приходится выстраивать код приложения ввидеобработчиков событий на сокетах.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 8: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/8.jpg)
Неблокирующий I/O
Использвование неблокирующего I/O кажется болееподходящим решением проблемы.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 9: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/9.jpg)
Неблокирующий I/O
Но какие распространённые библиотеки/фрэймворки мы имеемдля Python: asyncore, Twisted, Tornado.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 10: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/10.jpg)
С Twisted приходится писать асинхронный код – это неудобно!
def handle_client(req):deferred = make_api_request ()deferred.addCallback(handle_api_resp , req)deferred.addErrback(handle_error)return deferred
def handle_api_resp(api_resp , req):deferred = make_db_request ()deferred.addCallback(handle_db_resp , api_resp , req)return deferred
def handle_db_resp(db_resp , api_response , req):# work with api_resp and db_resprequest.write(" success ")
def handle_error(failure , req):# handle errorrequest.write("error")return failure
Андрей Попп: Разработка сетевых приложений с gevent
![Page 11: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/11.jpg)
Синхронный код писать проще и получается он понятнее.
def handle_client(request ):try:
api_response = make_api_request ()db_response = make_db_request ()# work with api_response and db_responserequest.write(" success ")
except Exception:request.write("error")raise
Но приходится использовать блокирующий I/O.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 12: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/12.jpg)
Что делать? Нужно искать компромис!
Андрей Попп: Разработка сетевых приложений с gevent
![Page 13: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/13.jpg)
Микропотоки
Микропотоки или “зелёные” потоки или userspace-потоки:
Это как функции, исполнение которых можноприостановить, а потом – продолжить.Работают внутри одного или нескольких потоков ОС.Для их исполнения необходим планировщик.Обычно дёшевы в плане потребления памяти ипереключения контекста.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 14: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/14.jpg)
Микропотоки + Неблокирующий I/O
Чтобы микропотоки исполнялись им необходим планировщик.
Предлагается следующий вариант:
Как только микропоток пытается выполнить I/O, онпередаёт управление планировщику.После того, как выполнение I/O становится доступным длямикропотока – планировщик возвращает ему управление.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 15: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/15.jpg)
Блокируется только микропоток, который пытается выполнитьI/O, а не весь интерпретатор.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 16: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/16.jpg)
Это называется кооперативная многозадачность – потоки самирешают когда передать исполнение другим.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 17: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/17.jpg)
Существует также преемптивная или вытесняющаямногозадачность – поток вытесняется планировщиком послеопределённого количества выполненных инструкций или по
истичении определённого времени.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 18: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/18.jpg)
Но разве микропотоки есть в Python?
Андрей Попп: Разработка сетевых приложений с gevent
![Page 19: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/19.jpg)
Микропотоки в Python – Генераторы
Можно реализовать микропотоки в Python c помощьюгенераторов (PEP 342, начиная с версии Python 2.5).
Чтобы передать исполнение – делаем yield.
К сожалению:
Кооперация с помощью yield – это слишком явно инеудобно, приходиться самим думать, когда отдаватьуправление.Генераторы не сохраняют весь стэк во время остановки –yield должен быть всегда на самом верху.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 20: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/20.jpg)
Микропотоки в Python – greenlet
Микропотоки с библиотекой greenlet:
Микропоток или просто гринлет это объект greenlet.Кооперация посредством вызова метода greenlet.switch.greenlet – это “выжимка” из Stackless Python.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 21: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/21.jpg)
Как работают гринлеты
from greenlet import greenlet
>>> def test1 ():... print ’one ’... gr2.switch ()... print ’two ’...>>> def test2 ():... print ’three ’... gr1.switch ()... print ’four ’...>>> gr1 = greenlet(test1)>>> gr2 = greenlet(test2)>>> gr1.switch ()onethreetwo
Андрей Попп: Разработка сетевых приложений с gevent
![Page 22: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/22.jpg)
Микропотоки реализованные с помощью greenlet удобны – онине страдают от недостатков генераторов.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 23: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/23.jpg)
Теперь нам нужен планировщик, который будет контролироватьисполнение гринлетов, руководствуясь событиями I/O.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 24: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/24.jpg)
gevent = libevent + greenlet
Такой планировщик предоставляет нам библиотека gevent.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 25: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/25.jpg)
Почему используется libevent
Почему gevent использует libevent для обработки событий:
Это быстрая библиотека, написанная на языке C – самцикл полностью в C коде.Libevent используется длительное время и хорошо себязарекомендовала (Chromium, Memcached, Io).Предоставляет встраиваемый HTTP-сервер – evhttp.Имеет API для работы с DNS – evdns.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 26: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/26.jpg)
Как устроен geventОбщая схема
Цикл обработки событий libevent работает в отдельномгринлете – этот гринлет называется хаб.Хаб запускается неявно и только при необходимости.Кооперация между гринлетами происходит через хаб:
Гринлет может переключиться только на хаб.Гринлет может получить управление только через хаб.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 27: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/27.jpg)
Как устроен geventОрганизация I/O
Чтобы совершить I/O наш гринлет должен:
1 Отправить запрос на I/O в цикл обработки событий.2 Переключиться на хаб.3 Хаб запускает выполнение других гринлетов.4 . . .5 Как только запрос на I/O выполнен, хаб переключается
обратно на наш гринлет.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 28: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/28.jpg)
Блокируется только гринлет, который пытается выполнить I/O,а не весь интерпретатор.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 29: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/29.jpg)
Сетевой I/O с gevent
Чтобы выполнять I/O гринлеты должны использоватькооперативный gevent.socket. Его API полностью повторяет
socket стандартной библиотеки Python.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 30: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/30.jpg)
Сетевой I/O с gevent
Кстати, gevent.socket.getaddrinfo,gevent.socket.gethostbyname используют evdns и тожеявляются блокирующими только для вызывающего их
гринлета.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 31: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/31.jpg)
Пример: конкурентный эхосервер с geventРеализация
from gevent import socket , spawn
def serve ((host , port), handler ):acceptor = socket.socket(socket.AF_INET , socket.STREAM)acceptor.bind((host , port))while True:
client , address = acceptor.accept ()spawn(handler , client , address)
def handler(sock , address ):f = sock.makefile ()while True:
line = f.readline ()if not line:
breakf.write(line)f.flush()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 32: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/32.jpg)
Пример: конкурентный эхосервер с geventОбработка соединений
Обработка соединения происходит в отдельном гринлете:
from gevent import socket , spawn
def serve ((host , port), handler ):acceptor = socket.socket(socket.AF_INET , socket.STREAM)acceptor.bind((host , port))while True:
client , address = acceptor.accept ()spawn(handler, client, address)
def handler(sock , address ):f = sock.makefile ()while True:
line = f.readline ()if not line:
breakf.write(line)f.flush()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 33: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/33.jpg)
Пример: конкурентный эхосервер с geventТочки кооперации
В этих точках гринлет отдаёт управление циклу libevent:
from gevent import socket , spawn
def serve ((host , port), handler ):acceptor = socket.socket(socket.AF_INET , socket.STREAM)acceptor.bind((host , port))while True:
client, address = acceptor.accept()spawn(handler , client , address)
def handler(sock , address ):f = sock.makefile ()while True:
line = f.readline()if not line:
breakf.write(line)f.flush()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 34: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/34.jpg)
Оказалось достаточно использовать gevent.socket вместоsocket и вызвать gevent.spawn в нужном месте.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 35: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/35.jpg)
Пример: конкурентный эхосервер с geventИспользуем StreamServer
Нужно использовать gevent.server.StreamServer:
from gevent.server import StreamServer
def handler(sock , address ):f = sock.makefile ()while True:
line = f.readline ()if not line:
breakf.write(line)f.flush()
StreamServer ((’localhost ’, 6000) , handler ). serve_forever ()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 36: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/36.jpg)
Мы умеем создавать новые гринлеты (gevent.spawn) ииспользовать gevent.socket. Посмотрим, что ещё мы можем
делать с gevent.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 37: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/37.jpg)
Базовые возможности geventЖдём завершения работы гринлета
Ждём пока гринлет прекратит свою работу:
>>> task = gevent.spawn(lambda a, b: a + b, 1, 2)>>> task.join()
Если нам нужен результат работы гринлета:
>>> task = gevent.spawn(lambda a, b: a + b, 1, 2)>>> task.get()3
В случае, если гринлет прекратил работу из-за исключения:
>>> task = gevent.spawn(lambda a, b: a / b, 1, 0)>>> task.get()Traceback (most recent call last):...ZeroDivisionError: integer division or modulo by zero
Андрей Попп: Разработка сетевых приложений с gevent
![Page 38: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/38.jpg)
Базовые возможности geventПреждевременное завершение гринлета
Чтобы завершить выполнение гринлета:
>>> task = gevent.spawn(lambda a, b: a + b, 1, 2)>>> task.kill()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 39: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/39.jpg)
Базовые возможности geventПриостанавливаем выполнение гринлета
Иногда нужно приостановить выполнение гринлета:
>>> def some_work ():... # do some work... gevent.sleep (10)... # continue
Функция gevent.sleep аналогична time.sleep, только“засыпает” не весь интерпретатор, а отдельный гринлет.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 40: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/40.jpg)
Базовые возможности geventОбработка таймаутов
Обработка таймаутов осуществляется с gevent.Timeout:
timeout = Timeout (10)timeout.start()try:
# do some workexcept gevent.Timeout:
# handle timeoutfinally:
timeout.cancel ()
. . . или как контекст-менеджер:
try:with gevent.Timeout (10):
# do some workexcept gevent.Timeout:
# handle timeout
Андрей Попп: Разработка сетевых приложений с gevent
![Page 41: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/41.jpg)
Управляем несколькими гринлетамиОбъединяем гринлеты в группы
Иногда нужно управлять несколькими гринлетами сразу:
>>> tasks = gevent.pool.GreenletSet ()>>> for i in range (10):... tasks.spawn(do_some_work , i)>>> tasks.join()
. . . или. . .
>>> tasks = gevent.pool.GreenletSet ()>>> tasks.map(lambda a: a**2, range (10))[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Андрей Попп: Разработка сетевых приложений с gevent
![Page 42: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/42.jpg)
Управляем несколькими гринлетамиРаботаем с пулом гринлетов
А иногда бывает нужно ограничить количество одновременновыполняемых гринлетов в группе:
>>> tasks = gevent.pool.Pool(size =5)>>> for i in range (10):... tasks.spawn(do_some_work , i)>>> tasks.join()
В данном случае будет одновременно исполняться только 5гринлетов.
Таким образом можно, например, ограничить количествоодновременно обрабатываемых соединений.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 43: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/43.jpg)
HTTP-сервисы с geventИспользуем evhttp
Модуль gevent.http предоставляет API для использованияevhttp, но нас больше интересует WSGI.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 44: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/44.jpg)
HTTP-сервисы с geventWSGI сервер
Модуль gevent.wsgi – реализация WSGI на базе gevent.http:
from gevent.wsgi import WSGIServer
def hello_world(environ , start_response ):start_response (’200 OK ’, [(’Content -Type ’, ’text/html ’)])return ["It works !"]
WSGIServer ((’localhost ’, 8000) , hello_world ). serve_forever ()
Можно использовать практически любой WSGIфрэймворк/библиотеку: Django, Werkzeug, WebOb, repoze.bfg,Pylons.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 45: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/45.jpg)
Используем gevent с другими библиотеками
Как уже говорилось, API gevent.socket полностью повторяетsocket из стандартной библиотеки Python.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 46: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/46.jpg)
Используем gevent с другими библиотекамиПредоставляем фабрику кооперативных сокетов
Если библиотека позволяет пользовательскому коду подменятькласс используемого сокета:
from somenetworklibrary import Clientfrom gevent import socket
class CooperativeGeventAwareClient(Client ):
def create_socket(self):sock = socket.socket(socket.AF_INET , socket.STREAM)return sock
Но что делать, если не позволяет?
Андрей Попп: Разработка сетевых приложений с gevent
![Page 47: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/47.jpg)
Используем gevent с другими библиотекамиMonkey patching
gevent предоставляет возможность пропатчить модуль socketстандартной библиотеки:
from gevent import monkeymonkey.patch_socket ()
После этого, код, который использует модуль socket будеткооперироваться.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 48: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/48.jpg)
Используем gevent с другими библиотекамиMonkey patching
Кроме этого в gevent.monkey:
patch_time() – заменяем time.sleep() накооперативный gevent.sleep().patch_thread() – создаём гринлеты вместо потоков ОС,также патчит threading.local.patch_os(), patch_ssl(), patch_select() – . . .patch_all() – патчим всё.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 49: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/49.jpg)
Пример: используем gevent с urllib2
from gevent.pool import Poolfrom gevent import monkeymonkey.patch_all ()import urllib2
tasks = Pool(size =20)
urls = [’http :// www.gevent.org ’, ...]
def print_head(url):print ’Starting %s’ % urldata = urllib2.urlopen(url).read()print ’%s: %s bytes: %r’ % (url , len(data), data [:50])
for url in urls:tasks.spawn(print_head , url)
tasks.join()
Андрей Попп: Разработка сетевых приложений с gevent
![Page 50: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/50.jpg)
Используем gevent с другими библиотеками
Я также использовал gevent совместно с SQLAlchemy, boto.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 51: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/51.jpg)
Где используется gevent
Несколько проектов, которые используют gevent:
Gunicorn – WSGI HTTP сервер, может использовать geventдля обработки запросов.pastegevent – используем gevent.wsgi для запуска WSGIприложений вместе с PasteDeploy.gevent-mysql – драйвер для MySQL, написанный на Cython,использующий API gevent.psycogreen – отдельная ветка psycopg, которая работает сасинхронными библиотеками, например с gevent.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 52: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/52.jpg)
Некоторые ограничения
Как это обычно бывает, существуют некоторые ограничения:
После os.fork() необходимо вызывать gevent.reinit().Библиотеку можно использовать только в одном потокеОС – ограничение libevent 1.4.Блокирующий stdin – вскоре будет исправлено.Библиотеки которые не используют socket блокируютинтерпретатор полностью – можно выполнять их вотдельном потоке ОС.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 53: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/53.jpg)
Какие темы я не затронул
Остались темы, которые я не затронул:
Линки между гринлетами.Примитивы синхронизации – gevent.event.Синхронные очереди – gevent.queue.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 54: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/54.jpg)
Полезные ссылки
http://gevent.org – официальный сайт и документация.
http://bitbucket.org/denis/gevent/ – исходный код.
http://groups.google.com/group/gevent – рассылка.
http://blog.gevent.org/ – блог проекта.
http://twitter.com/gevent – twitter проекта.
И наконец #gevent на irc.freenode.net.
Андрей Попп: Разработка сетевых приложений с gevent
![Page 55: Разработка сетевых приложений с gevent](https://reader036.fdocuments.net/reader036/viewer/2022081801/54825a195806b5de048b4659/html5/thumbnails/55.jpg)
Спасибо!
Андрей Попп: Разработка сетевых приложений с gevent