Pure python implementacja greenlet API
Pakiet greenlet jest używany przez gevent i eventlet do asynchronicznego IO. Jest napisany jako rozszerzenie C i dlatego nie działa z Jython lub IronPython. Jeśli wydajność nie ma znaczenia, jakie jest najprostsze podejście do implementacji greenlet API w czystym Pythonie.
Prosty przykład:
def test1():
print 12
gr2.switch()
print 34
def test2():
print 56
gr1.switch()
print 78
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()
Powinny drukować 12, 56, 34 (a nie 78).
2 answers
Tego typu rzeczy można osiągnąć dzięki Ko-procedurom, które zostały wbudowane w standardową dystrybucję Pythona od wersji 2.5. Jeśli IronPython i co są w pełni zgodne ze wszystkimi funkcjami Pythona 2.5 (wierzę, że są), powinieneś być w stanie użyć tego idiomu.
Zobacz Ten post aby uzyskać więcej informacji o tym, jak można je wykorzystać:) szczególnie zainteresuje cię PDF gdzie autor buduje system używając tylko czystego Pythona, który zapewnia podobne możliwości albo stackless Python lub moduł Greenlet.
Możesz również poszukać Gogena lub kamelii dla pomysłów: oba projekty mają czyste implementacje Pythona coroutine, które możesz zaadoptować lub użyć jako odniesienia do własnej implementacji. Spójrz na tę stronę , aby delikatnie wprowadzić w cogen
sposób robienia rzeczy.
Zauważ, że istnieją pewne różnice między implementacjami co-routine i greenlet
implementacja. Wszystkie implementacje Pythona używają jakiegoś zewnętrznego harmonogramu, ale idea jest zasadniczo taka sama: zapewniają sposób na uruchamianie lekkich, współpracujących zadań bez konieczności uciekania się do wątków. Dodatkowo oba frameworki powiązane z powyższym są nastawione na asynchroniczne IO bardzo podobne do samego greenlet
.
Oto przykład, który napisałeś, ale przepisałeś za pomocą 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
Jest nieco bardziej wyrazista niż wersja greenlet
(dla przykład używając WaitForSignal
aby jawnie utworzyć punkt CV), ale powinieneś uzyskać ogólny pomysł.
Edit: właśnie potwierdziłem, że to działa przy użyciu jython
KidA% jython test.py
12
56
34
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-07 17:20:35
Nie jest możliwe zaimplementowanie greenleta w czystym Pythonie.
UPDATE:
- udawanie greenlet API z wątkami może być rzeczywiście wykonalne, nawet jeśli całkowicie bezużyteczne dla wszystkich praktycznych celów
- Generatory nie mogą być używane do tego celu, ponieważ zapisują tylko stan pojedynczej klatki. Greenlets zapisać cały stos. Oznacza to, że gevent może używać dowolnego protokołu zaimplementowanego na standardowym gnieździe (np. Moduły httplib i urllib2). Framework oparty na generatorze wymaga Generatory we wszystkich warstwach oprogramowania, więc httplib i tony innych pakietów są wyrzucane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-28 08:58:19