Чистая реализация Python API, которому дают зеленый свет,

Пакет, которому дают зеленый свет, используется gevent и eventlet для асинхронного IO. Это записано как C-расширение и поэтому не работает с Jython или IronPython. Если производительность не вызывает беспокойства, что самый легкий подход к реализации API, которому дают зеленый свет, в чистом Python.

Простой пример:

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

Должен распечатать 12, 56, 34 (а не 78).

20
задан Tristan 3 June 2010 в 17:19
поделиться

2 ответа

Такого рода вещи могут быть достигнуты с помощью ко-программ, которые встроены в стандартный дистрибутив Python с версии 2.5. Если IronPython и co полностью совместимы со всеми возможностями Python 2.5 (я полагаю, что это так), вы должны иметь возможность использовать эту идиому.

См. этот пост для получения дополнительной информации о том, как их можно использовать :) В частности, вас заинтересует PDF, где автор строит систему, не используя ничего, кроме чистого Python, которая предоставляет возможности, схожие с возможностями stackless Python или модуля Greenlet.

Возможно, вам также стоит обратить внимание на Gogen или Kamelia: в этих проектах реализованы корутины на чистом python, которые вы можете либо перенять, либо использовать в качестве эталона для собственной реализации. Посмотрите на эту страницу для мягкого введения в cogen способ делать вещи.

Обратите внимание, что есть некоторые различия между реализацией ко-рутины здесь и greenletреализацией. Реализации на чистом python все используют какой-то внешний планировщик, но идея, по сути, одна и та же: они предоставляют вам способ запускать легкие, кооперативные задачи без необходимости прибегать к потокам. Кроме того, оба упомянутых выше фреймворка ориентированы на асинхронный ввод-вывод, как и сам greenlet.

Вот пример, который вы опубликовали, но переписанный с использованием cogen:

from cogen.core.coroutines import coroutine
from cogen.core.schedulers import Scheduler
from cogen.core import events

@coroutine
def test1():
    print 12
    yield events.AddCoro(test2)
    yield events.WaitForSignal(test1)
    print 34

@coroutine
def test2():
    print 56
    yield events.Signal(test1)
    yield events.WaitForSignal(test2)
    print 78

sched = Scheduler()
sched.add(test1)
sched.run()

>>> 12
>>> 56
>>> 34

Он немного более явный, чем версия greenlet (например, использование WaitForSignal для явного создания точки возобновления), но вы должны уловить общую идею.

edit: I just confirmed that this works using jython

KidA% jython test.py 
12
56
34
12
ответ дан 30 November 2019 в 01:05
поделиться

Невозможно реализовать гринлет на чистом Python.

ОБНОВЛЕНИЕ:

  • поддельный API-интерфейс Greenlet с потоками может быть действительно выполнимым, даже если он совершенно бесполезен для всех практических целей.
  • генераторы не могут быть использованы для этого, поскольку они сохраняют состояние только одного кадра. Гринлеты сохраняют весь стек. Это означает, что gevent может использовать любой протокол, реализованный поверх стандартного сокета (например, модули httplib и urllib2). Фреймворки на основе генераторов требуют генераторов на всех уровнях вашего программного обеспечения, поэтому httplib и множество других пакетов выбрасываются.
10
ответ дан 30 November 2019 в 01:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: