Пакет, которому дают зеленый свет, используется 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).
Такого рода вещи могут быть достигнуты с помощью ко-программ, которые встроены в стандартный дистрибутив 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
Невозможно реализовать гринлет на чистом Python.
ОБНОВЛЕНИЕ: