Portál AbcLinuxu, 30. dubna 2025 14:03

Návrat do budoucnosti v Pythonu

18.4.2007 22:49 | Přečteno: 1243× | Dev/Tech/Gnu | Výběrový blog | poslední úprava: 18.4.2007 22:50

Minule jsem psal o tom, jak jdou se zásobníkem v Pypy dělat psí kusy. Uvedený příklad byl ale jen taková onanie. Dnes tu mám opravdovější příklad. Jedná se o funkci fork() modulu _stackless. Co tahle funkce dělá? Inu přesně to, co její jmenovkyně z pravého Unixu, jen nevytvoří nový proces, ale korutinu (takové lehkotonážní vlákno, které nemá preempci a musí se přepínat explicitně). Funkce se tedy vrátí "dvakrát". Po vyvolání zůstane provádění v hlavní korutině a tato korutina dostane referenci na nově vytvořenou synovskou korutinu. V synovské korutině vrátí fork hodnotu None. K čemu je to dobré? Představte si, že zavoláte nějakou funkci a dostanete její návratovou hodnotu. Nějakou dobu s touto návratovou hodnotou počítáte, ale pak zjistíte, že tato návratová hodnota se vám nějak nehodí do krámu. Vyvoláte tedy výjimku a program se vrátí v čase až do volání inkriminované funkce a tato funkce se pokusí vám poskytnout lepší návratovou hodnotu. Sci-fi? Mrkněte na následující příklad.
# this is pyfork.py
from _stackless import fork, coroutine, clonable

class Fail(Exception):
	pass

def zero_or_one():
	subcoro = fork()
	if subcoro is not None:
		try:
			subcoro.switch() # in the parent: run the child first
		except Fail:
			pass
			
		return 1   # then proceed with answer 1
	else:
		return 0   # in the child: answer 0

def f():
	num = zero_or_one();
	
	if num == 0:
		print "zero is not good enough!"
		raise Fail
	
	print "we got ONE: ", num

def main():
	#just because fork() is not enabled in main routine
	coro = clonable()
	coro.bind(f)
	coro.switch()
	print "Done"

main()
Funkce zero_or_one vrací nulu nebo jedničku. Řekněme, že se nám ve funkci f nula ani trochu nelíbí. Vyvoláme výjimku Fail nastane návrat do minulosti. (Mimochodem, BTTF a Michaela J. Foxe mám fakt rád.) Samotná funkce zero_or_one funguje následovně. Fork vytvoří novou korutinu a reference na ni se uloží do proměnné subcoro. Provádění pokračuje v hlavní korutině (taže následující podmínka se vyhodnotí jako True). Jenže pak následuje přepnutí na synovskou korutinu, a funkce nakonec vrátí nulu. Když se ve funkci f vyvolá výjimka, tak se propaguje až do místa, kde synovská korutina započala svůj běh (tedy subcoro.switch()). Synovská korutina de-facto končí a výjimka se propaguje až do rodičovské korutiny (tohle je asi největší magie). Tam je výjimka ošetřena a funkce vrátí jedničku.

Demonstrace

Aby tohle fungovalo, je potřeba Pypy přeložit do Céčka s následujícími parametry:
$ python translate.py --stackless --gc=framework --batch targetpypystandalone.py
Pak se to pustí příkazem
$ ./pypy-c pyfork.py
a vypíše
zero is not good enough!
we got ONE:  1
Done
       

Hodnocení: 80 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

18.4.2007 23:46 Kyosuke | skóre: 28 | blog: nalady_v_modre
Rozbalit Rozbalit vše Re: Návrat do budoucnosti v Pythonu
Odpovědět | Sbalit | Link | Blokovat | Admin
Nebylo by „poněkud“ inteligentnější místo vyhození výjimky do jiného vlákna prostě zavolat kontinuaci, která existuje přesně kvůli tomuhle účelu?
Jak moc jsou ábíčkáři inteligentní? ;-)
18.4.2007 23:49 paskma | skóre: 13 | blog: Paskmův blog
Rozbalit Rozbalit vše Re: Návrat do budoucnosti v Pythonu
Něco proti Unixu?-)

Asi ano, ale tohle mi přišlo zábavnější.
19.4.2007 10:40 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Návrat do budoucnosti v Pythonu
ona to vlastne kontinuace je... jenom ten stav zasobniku uklada jinak...
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
19.4.2007 11:10 Kyosuke | skóre: 28 | blog: nalady_v_modre
Rozbalit Rozbalit vše Re: Návrat do budoucnosti v Pythonu
No je taková hodně explicitní. :-) Ale čím jsou odlehčenější, tím líp. :-)

Založit nové vláknoNahoru

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.