Ważnym wprowadzeniem będzie teoria na wikipedii dotycząca Distributed computing. Są różne podejścia do reazlizacji wielowątkowości i jej synchronizajci. Zasadniczo doceniam w tym artykule specyficzne, bo posiadające w API dosłownie kilka funkcji. Zaimplementowanych w taki sposób, że aż się miło testuje i wdraża takie rozwiązanie. Oczywiście porównuję tutaj API systemowe np: WINAPI i POSIX THREADS. Jest z tym nieco zabawy w projektowaniu i kodowaniu, dlatego przedstawiam Stackless Python, który może rowiązać więcej problemów niż tylko wymienione niewygody wielowątkowości w naszym systemie operacyjnym.
Okazuje się, że programowanie wielowątkowe na większą skalę wcale nie musi posiadać skomplikowanego API. Projektanci Stackless Python doskonale o tym wiedzieli i uprościli bazowe elementy API do następujących pojęć:
- Tasklets
- The Scheduler
- Channels
Zacznę od bazowego przykładu, który pokazuje, jak rozpocząć zabawę z tą technologią. Do wykonania poniższego kodu będzie potrzebna obecność w naszym systemie pypy-stackless.
Tasklets są podstawowym budulcem dla stackless. Możesz utworzyć zadania tasklet przez dodanie zwykle funkcji lub metody klasy. Stworzony w ten sposób tasklet zostaje dodany do harmonogramu zadań. Zauważ, że kolejka taskletów i nie działaja, dopóki nie nastąpi wywołanie metody stackless.run().
Oto prosta demonstracja:
# example1.py
import stackless
def print_x(x):
print x
stackless.tasklet(print_x)('one')
stackless.tasklet(print_x)('two')
stackless.tasklet(print_x)('three')
stackless.run()
Uruchamianie przykładu oraz rezultaty działania:
$ pypy-stackless example1.py
one
two
three
Scheduler kontroluje kolejność, w jakiej tasklets są uruchamiane. Jeśli po prostu stworzysz kilka taskletów, będą uruchamiane w kolejności, w jakiej zostały utworzone. W ogólnej praktyce będzie to związane ze stworzeniem i wywołaniem dodanych taskletów za każdą iteracją ogólnego mechnizmu obiegu danych.
Zauważ, że gdy wywołujemy stackless.schedule(), aktywnym tasklet zatrzymuje się i ponownie wstrzykuje się do końca schedulera w kolejce, pozwalając następnemu taskletowi uruchomić się. Gdy wszystkie z aktywnych taskletów zostaną uruchomione, następuje przywoływanie pozostałych. To trwa do zakończenia wszystkich aktywnych taskletów. W ten sposób osiągamy wielowątkowość we współpracy z stackless.
Szybka demonstracja:
# example2.py
import stackless
def print_three_times(x):
print "1:", x
stackless.schedule()
print "2:", x
stackless.schedule()
print "3:", x
stackless.schedule()
stackless.tasklet(print_three_times)('first')
stackless.tasklet(print_three_times)('second')
stackless.tasklet(print_three_times)('third')
stackless.run()
Uruchamianie przykładu oraz rezultaty działania:
$ pypy-stackless example2.py
1: first
1: second
1: third
2: first
2: second
2: third
3: first
3: second
3: third
Channels czyli kanały umożliwiają wysyłanie informacji między tasklets. To realizuje dwie rzeczy:
Pozwala to na wymianę informacji między tasklets.
Pozwala to na kontrolę przepływu egzekucji.
Kolejna szybka demonstracja:
# example3.py
channel = stackless.channel()
def receiving_tasklet():
print "Recieving tasklet started"
print channel.receive()
print "Receiving tasklet finished"
def sending_tasklet():
print "Sending tasklet started"
channel.send("send from sending_tasklet")
print "sending tasklet finished"
def another_tasklet():
print "Just another tasklet in the scheduler"
Uruchamianie przykładu oraz rezultaty działania:
$ pypy-stackless example3.py
Recieving tasklet started
Sending tasklet started
send from sending_tasklet
Receiving tasklet finished
Just another tasklet in the scheduler
sending tasklet finished
Kilkoma słowami chciałbym podsumować opisane rozwiązanie w Stackless Python. Po pierwsze ilość dostępnych funkcji w API oraz sposób ich użycia szczególnie zachęca do zgłębiania i używania (4 - 6 funkcji). Zarazem niesamowitym osiągnięciem jest fakt, że tak wielki projekt gry on-line jak EVE bazuje na tak prostym i wydajnym rozwiązaniu.
Zachęcam do opisania swoich doświadczeń ze Stackless Python w komentarzach, chętnie podyskutuję.
Mariały dodatkowe:
Stackless Python Homepage
why stackless
Is Stackless Python for You?
Introduction to Concurrent Programming with Stackless Python
Wątki
http://www.archivum.info/pl.comp.lang.python/2008-03/msg00119.html
http://forum.gamedev.pl/index.php?action=printpage%3Btopic=6678.0
Kurs Pisania OS
Debug pamięci w Linuksie (pamięć od strony technicznej)
Dynamiczne zarządzanie pamięcią w C bez wycieków
Stackless Python - artykuly
CORBA Guru Steve Vinoski on REST, Web Services, and Erlang
5 komentarzy:
http://entitycrisis.blogspot.com/2009/06/gil-vs-stackless-benchmarks.html
http://code.google.com/p/fibra/
http://seun-python.blogspot.com/2009/06/gil.html
http://entitycrisis.blogspot.com/2009/03/concurrent-scaling-benchmarks.html
http://entitycrisis.blogspot.com/2009/03/benchmarking-stackless-kamaelia-and.html
Prześlij komentarz