(Давным-давно) я написал веб-паук, который я многопоточный для одновременного выполнения запросов. Это было в моей юности Python, в те дни, когда я знал о GIL и связанных с ним проблемах, которые он создает для многопоточного кода (IE, в большинстве случаев, все просто заканчивается сериализацией!) ...
Я хотел бы переработать этот код, чтобы сделать его более надежным и работать лучше. В принципе, я мог бы сделать это двумя способами: я мог бы использовать новый многопроцессорный модуль в версии 2.6+ или использовать модель, основанную на реакторах / событиях. Я бы предпочел сделать позже, так как это намного проще и менее подвержено ошибкам.
Таким образом, вопрос касается того, какая структура будет лучше всего соответствовать моим потребностям. Ниже приведен список параметров, о которых я знаю:
- Twisted : дедушка Python каркас реактора: кажется сложным и немного раздутым, однако. Крутая кривая обучения для небольшой задачи.
- Eventlet : От парней из Lindenlab . Фреймворк на основе Greenlet, предназначенный для решения подобных задач. Хотя я взглянул на код, и он не слишком красивый: не соответствует pep8, разбросан по принтам (почему люди делают это в рамках !?), API кажется немного непоследовательным.
- PyEv : Незрелый, похоже, никто не использует его сейчас, хотя он основан на libevent, поэтому у него есть солидный бэкэнд.
- asyncore : из stdlib: über low-level, кажется, что нужно приложить много усилий, чтобы просто что-то поднять.
- tornado : Хотя это серверный продукт, предназначенный для динамических веб-сайтов, в нем есть асинхронный HTTP-клиент и простой ioloop . Похоже, что это может сделать работу, но не то, для чего она была предназначена. [править: к сожалению, не работает в Windows, что для меня важно - это требование для меня, чтобы поддерживать эту слабую платформу]
Я что-то пропустил? Конечно, должна существовать библиотека, которая подходит для сладкой асинхронной сетевой библиотеки!
[edit: большое спасибо intgr за указатель на эту страницу . Если вы прокрутите вниз, то увидите, что есть действительно хороший список проектов, которые нацелены на то или иное решение этой задачи. Похоже, что с момента появления Twisted все действительно пошло дальше: теперь люди предпочитают решение, основанное на совместной рутине, а не традиционное решение, ориентированное на реактор / обратный вызов. Преимущества этого подхода заключаются в более четком и понятном коде: я наверняка обнаружил это в прошлом, особенно при работе с boost.asio.в C ++ этот код, основанный на обратном вызове, может привести к проектам, которые могут быть трудны для понимания и относительно неясны для неопытного глаза. Использование сопрограмм позволяет вам писать код, который выглядит как минимум немного более синхронным. Думаю, теперь моя задача - выяснить, какая из этих многочисленных библиотек мне нравится, и попробовать! Рад, что спросил сейчас ...]
[править: возможно, представляет интерес для тех, кто следил или наткнулся на этот вопрос или в какой-то мере интересуется этой темой: я нашел действительно отличную рецензию на текущее состояние доступных инструментов для этой работы]
select
для мультиплексирования ввода / вывода. Но вы должны быть в состоянии получить достойную производительность из этого с торнадо-пьюв . 2. В Python 3.3+ и его троллее backport теперь есть asyncio, который позволяет запускать любое приложение Tornado в цикле событий (Twisted будет поддерживаться в ближайшее время).Ответы:
Мне понравился модуль Python для параллелизма, который использует микропотоки Stackless Python или Greenlets для облегчения потоков. Все блокирующие сетевые операции ввода / вывода прозрачно делаются асинхронными через один
libevent
цикл, поэтому он должен быть почти таким же эффективным, как настоящий асинхронный сервер.Я предполагаю, что это похоже на Eventlet таким образом.
Недостатком является то, что его API сильно отличается от модулей
sockets
/ Pythonthreading
; вам нужно переписать значительную часть вашего приложения (или написать слой совместимости совместимости)Редактировать: Кажется, что есть также Cogen , который похож, но использует расширенные генераторы Python 2.5 для своих сопрограмм, а не Greenlets. Это делает его более портативным, чем совпадение и другие альтернативы. Сетевой ввод-вывод выполняется напрямую с помощью epoll / kqueue / iocp.
источник
Скручивать сложно, вы правы в этом. Витая не раздутая.
Если вы посмотрите здесь: http://twistedmatrix.com/trac/browser/trunk/twisted вы найдете организованный, всеобъемлющий и очень хорошо протестированный набор многих протоколов Интернета, а также вспомогательный код для написания и развертывать очень сложные сетевые приложения. Я бы не перепутал раздувание со всесторонностью.
Хорошо известно, что документация Twisted не является самой удобной с первого взгляда, и я считаю, что это отвлекает несчастное количество людей. Но Twisted это удивительно (ИМХО), если вы вкладываете время. Я сделал, и это оказалось того, и я бы порекомендовал другим попробовать то же самое.
источник
gevent - это очищенный eventlet .
API-интерфейс следует тем же соглашениям, что и стандартная библиотека (в частности, многопоточные и многопроцессорные модули), где это имеет смысл. Таким образом, у вас есть знакомые вещи, такие как Очередь и Событие, с которыми можно работать.
Он поддерживает только libevent ( update: libev начиная с 1.0 ) в качестве реализации реактора, но в полной мере использует его, предоставляя быстрый WSGI-сервер на основе libevent-http и разрешая DNS-запросы через libevent-dns, в отличие от использования пула потоков, как и большинство других библиотек. делать. ( обновление: начиная с 1.0 c-ares используется для выполнения асинхронных DNS-запросов; также возможен пул потоков).
Как и eventlet, он делает обратные вызовы и отложенные ссылки ненужными с помощью гринлетов .
Посмотрите примеры: одновременная загрузка нескольких URL , длинный опрос в чате .
источник
Очень интересное сравнение таких фреймворков было составлено Николасом Пиелем в его блоге: его стоит прочитать!
источник
Ни одно из этих решений не избежит того факта, что GIL предотвращает параллелизм ЦП - это всего лишь лучший способ получить параллелизм ввода-вывода, который у вас уже есть с потоками. Если вы считаете, что можете улучшить IO, обязательно выполните одно из этих действий, но если ваше узкое место заключается в обработке результатов, здесь ничего не поможет, кроме модуля многопроцессорной обработки.
источник
Я бы не пошел так далеко, чтобы назвать Twisted раздутым, но трудно обернуть голову вокруг. Я довольно долго избегал действительно учиться, потому что всегда хотел чего-то более легкого для «небольших задач».
Тем не менее, теперь, когда я поработал с ним еще немного, я должен сказать, что все батареи в комплекте ОЧЕНЬ приятно.
Все остальные асинхронные библиотеки, с которыми я работал, в конечном итоге оказываются менее зрелыми, чем кажутся. Цикл событий Twisted является твердым.
Я не совсем уверен, как решить крутой витой кривой обучения. Это может помочь, если кто-то раскошелится и почистит несколько вещей, например, удалит всю обратную совместимость и мертвые проекты. Но это природа зрелого программного обеспечения, я думаю.
источник
PortableGtkReactor
?Камаэлия еще не упоминалась. Его модель параллелизма основана на соединении компонентов с передачей сообщений между входящими и исходящими сообщениями. Вот краткий обзор.
источник
Я начал использовать витой для некоторых вещей. Его красота почти в том, что он «раздутый». Существуют разъемы практически для любых основных протоколов. У вас может быть jabber-бот, который будет принимать команды и публиковать их на irc-сервере, отправлять их кому-либо по электронной почте, запускать команды, читать с NNTP-сервера и отслеживать изменения на веб-странице. Плохая новость в том, что он может делать все это и может слишком усложнять выполнение простых задач, таких как объяснение ОП. Преимущество Python в том, что вы включаете только то, что вам нужно. Таким образом, хотя загрузка может быть 20 МБ, вы можете включить только 2 МБ библиотек (что все еще много). Моя самая большая претензия к Twisted заключается в том, что они включают примеры, что угодно, кроме базового tcp-сервера, который вы можете использовать самостоятельно.
Хотя я и не являюсь решением на python, я видел, что node.js в последнее время набирает обороты На самом деле, я подумывал о том, чтобы изучить его для небольших проектов, но я просто съеживаюсь, когда слышу javascript :)
источник
На эту тему есть хорошая книга Абэ Феттига "Основы программирования для витой сети". Примеры показывают, как писать очень Pythonic-код, и лично мне, не кажется мне основанным на раздутой структуре. Посмотрите на решения в книге, если они не чистые, тогда я не знаю, что такое чистый.
Моя единственная загадка такая же, как и у других фреймворков, таких как Ruby. Я волнуюсь, это масштабируется? Я бы не хотел привязывать клиента к среде, которая будет иметь проблемы с масштабируемостью.
источник
Whizzer - это крошечный асинхронный фреймворк, использующий pyev. Это очень быстро, в первую очередь из-за пыев. Он пытается создать похожий интерфейс, слегка измененный.
источник
Также попробуйте Syncless . Он основан на сопрограммах (поэтому он похож на Concurrence, Eventlet и gevent). Он реализует вставные неблокирующие замены для socket.socket, socket.gethostbyname (и т. Д.), Ssl.SSLSocket, time.sleep и select.select. Это быстро. Для этого нужен Stackless Python и libevent. Он содержит обязательное расширение Python, написанное на C (Pyrex / Cython).
источник
Подтверждаю доброту syncless . Он может использовать libev (более новая, более чистая и более производительная версия libevent). Некоторое время назад у него не было такой поддержки, как у libevent, но теперь процесс разработки идет дальше и очень полезен.
источник
Если вам нужна упрощенная и легкая библиотека HTTP-запросов, тогда я нахожу Unirest действительно хорошим
источник
Вы можете взглянуть на PyWorks, который использует совершенно другой подход. Он позволяет экземплярам объекта работать в своем собственном потоке и вызывает функции для этого объекта асинхронно.
Просто позвольте классу наследовать от Task вместо объекта, и он асинхронный, все вызовы методов являются прокси. Возвращаемые значения (если они вам нужны) являются будущими прокси.
PyWorks можно найти на http://bitbucket.org/raindog/pyworks
источник