Zabiti vypočtu v pythonu. – Python – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Zabiti vypočtu v pythonu. – Python – Fórum – Programujte.comZabiti vypočtu v pythonu. – Python – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Fstekly maltezak
~ Anonymní uživatel
4 příspěvky
23. 2. 2009   #1
-
0
-

Ahoj mám problém a to tento :

# Vymyslel jsem tohle abych zabil funkci loop() - respektive vypocet v ni ktery bezi dele nez chci.
# Funguje to, ale...
import time
import threading
a=55654
def loop():
while(1):
print "a*a"
try:
print a*a # pokud tady bude a**a tak to vyresit neumim. Zakousne se a nehne!
time.sleep(0.50)
except:
print " uleva !"
break
t=threading.Timer(0.0, loop)
t.start()
time.sleep(5.50)
a="DIE!"
raw_input()
# Jak prerusit prave probihajici vypocet a**a ?? Pripadne jak jinak by se toto dalo resit ??

Děkuji

Nahlásit jako SPAM
IP: 78.136.164.–
Reklama
Reklama
Quiark0
Věrný člen
23. 2. 2009   #2
-
0
-

Tuším, že to bude výsledek global interpreter locku - když se počítá a*a, tak žádný jiný kód kvůli tomu neběží, takže ho ani nemůže zastavit. Pokud to tak je, tak s tím nic moc nenaděláš.

Nahlásit jako SPAM
IP: 89.102.6.–
Koumes21
~ Anonymní uživatel
18 příspěvků
23. 2. 2009   #3
-
0
-

Quiark napsal:
Tuším, že to bude výsledek global interpreter locku - když se počítá a*a, tak žádný jiný kód kvůli tomu neběží, takže ho ani nemůže zastavit. Pokud to tak je, tak s tím nic moc nenaděláš.


Nechci působit nějak hrubě, ale to je hloupost. GIL sice způsobuje, že v jednom okamžiku běží jen jedna část kódu, ale mezi těmito částmi přepíná. Jde o to, že zavoláním "a**a" se zavolá jakási funkce umocni() s parametry (a,a), které se v tomto případě předávají hodnotou, tudíž pozdější změna "a" nijak neovlivní to, co se dostalo do umocňovací funkce. Nejjednodušší je pravděpodobně rozebrat "a**a" na menší kroky, které nebudou zabírat tak velký časový úsek. Také by to chtělo trochu změnit způsob zabití vlákna. Sice je pravda, že Python je tolerantní jazyk a právě díky GIL se nemůže stát, že by se v tomto programu něco zkazilo, ale v jakémkoliv jiném jazyce by čtení z proměnné a zároveň probíhající zápis do ní vedlo k nedefinovanému chování. Pokud by tě zajímalo, jak bych tuto úlohu řešil já, posílám ti svůj kód.


import time
import threading

class locked_var:
def __init__(self,var):
self.lock=threading.Lock()
self.var=var
def set(self,var):
self.lock.acquire()
self.var=var
self.lock.release()
def get(self):
self.lock.acquire()
ret=self.var
self.lock.release()
return ret

class loop_thread(threading.Thread):
def __init__(self,condition,a):
threading.Thread.__init__(self)
self.condition=condition
self.a=a
self.res=0
def run(self):
n=1
res=self.a
while self.condition.get() and n<self.a:
# dokud to neni zpocitano nebo neni vlakno ukonceno
res*=self.a
n+=1
print "bylo zpocitano a**"+str(n)
self.res=res
self.condition.set(True) # oznam, ze byl vysledek ulozen

a=55654
cond=locked_var(True)
t=loop_thread(cond,a)
print "startuji vlakno s parametrem "+str(a)
t.start()
time.sleep(5.5)
print "posilam signal na zastaveni..."
cond.set(False)
while not cond.get(): time.sleep(0.1) # cekame, az se vlakno doopravdy zastavi
# a ulozi vysledek
# vysledek je nyni v t.res
print "\nted jdu vysledek vytisknout, ale protoze"
print "ho nejdrive musim prevest z cisla na retezec,"
print "muze to trvat i nekolik minut"
print t.res
print "\nhotovo"
raw_input()

Nahlásit jako SPAM
IP: 212.24.152.–
Quiark0
Věrný člen
23. 2. 2009   #4
-
0
-

Hm, asi jsem si blbě přečetl otázku.

Nahlásit jako SPAM
IP: 89.102.6.–
Fstekly maltezak
~ Anonymní uživatel
4 příspěvky
23. 2. 2009   #5
-
0
-

Koumes21: Velice děkuji za Váš příspěvěk. Vaše řešení bude pro mne jistě velkou inspirací, ale pár dní ho budu chroustat, protože jsem naprostý začátečník. Ten kód je plný míst kterým nerozumím. Mohl bych Vás poprostit, aby jste ho opoznámkoval? Snad se pak v tom doberu nějakého řešení. V tomto stavu je pro mě nepoužitelný protože ono "a**a" se generuje náhodně. - Přesněji ten program generuje jakýkoliv náhodný polynom, který pak počítá a na místě "a**a" tedy může být klidně například. :

s=s*j(5142-(f(a**11407))**(-4429.86681**(-80393.862)))
# Dále je pak takových to řádků pod sebou v jednom výpočtu několik.
s=(s+-4*(2905.4*(a(m(p)))))
s=s...
(S tím že j,f je libovolná matematická funkce například sin... atd.) Proto mě zajímalo pouze jak co nejrychlejším způsobem zabít určytý výpočet přípedně funkci s tím, že není nutné nijak zachovat výsledek. Zajímalo by mě klidně jakkoliv násilné a hrubé přerušení výpočtu. Pokud nastane situace např. a**a a nebo jiná která by trvala příliš dlouho je vzorec nepoužitelný a není nutné se s ním dále zabývat.
Poslal bych sem celý program, ale věřím že by jste se v něm nechtěl vyznávat :o)) ... toto je poslední problém který v něm mám mám. Každopádně ještě jednou děkuji za Váš čas.

Nahlásit jako SPAM
IP: 78.136.150.–
Fstekly maltezak
~ Anonymní uživatel
4 příspěvky
23. 2. 2009   #6
-
0
-

... případně ještě by mě tedy tajímalo jestli jde nastavit tedy thread tak, aby by spustil nějakou funkci, ale dal jí na dokončení jen určitý počet sekund. Například 5. Pokud by funkce nedošla do konce do pěti sekund, tak by byla prostě ukončena. Prostě opak
"t=threading.Timer(5.0, loop) "

Děkuji.

Nahlásit jako SPAM
IP: 78.136.150.–
koumes21
~ Anonymní uživatel
18 příspěvků
23. 2. 2009   #7
-
0
-

Operační systém většinou povoluje zabití vlákna, jenže problém je, že vlákno nedostane příležitost po sobě uklidit. Některé programovací jazyky dají programátorovi příležitost vlákno zabít, Python ovšem nikoliv, protože je jaksi zaměřen na začátečníky a nechce jim dávat do rukou zbraň hromadného ničení, kterou neumí ovládat. Nejlepší by bylo, kdybys měl možnost nějak výrazy zjednodušit, například vkládáním funkcí do pole a voláním jedné funkce po druhé.

funkce = [

lambda x: 2*x+1,
lambda x: x+5,
lambda x: x/2
]

n=1
for f in funkce:
n=f(n)
print n

Pokud ovšem jsou výrazy generovány náhodně, může být složité je takto zjednodušit.
P.S.: Dobře, možná existuje možnost jak zabít vlákno. Našel jsem ukázku kódu v Pythonu, který by toto měl dělat, viz. http://www.velocityreviews.com/forums/t330554-kill-a-thread-in-python.html, ale protože ho sám nehodlám použít, budeš muset zjistit detaily jeho použití sám. Znovu opakuji, že je možné, že nebude fungovat absolutně tak jak má a že bude dělat problémy - zaseknutí programu, nadměrné zaplňování paměti atd.

Nahlásit jako SPAM
IP: 212.24.152.–
koumes21
~ Anonymní uživatel
18 příspěvků
23. 2. 2009   #8
-
0
-

ještě ke komentářům k programu: třída locked_var je náhrada za tvou původní globální proměnnou a, ale je bezpečné volat funkce get() a set() ze dvou různých vláken současně, protože třída používá zámek, který před čtením nebo zápisem zamkne a potom zase odemkne. Nepamatuji si, jestli je v dokumentaci Pythonu něco o tom, že GIL tohle zajistí pro každou proměnnou, je to možné, ale i tak je lepší používat tento postup, i kdyby to mělo být jen kvůli tomu, že to tak je v jiných jazycích. Třída loop_thread je náhrada za tvoje loop(), dejme tomu, že je ekvivalentní, ale podle mě je rozumnější použít klasickou cestu, neboť Timer slouží ke spuštění funkce po nějakém čase, což není přesně to co chceme. loop_thread.__init__() si pouze uloží parametry, které jí předáme a zavolá __init__() funkci třídy threading.Thread, ze které je odvozená. Funkce run() je potom ta funkce, která bude zavolána v novém vlákně až zavolám start(), která je zděděna z threading.Thread.
Ještě si dovolím konstruktivní kritiku ke tvému programu: nepoužívej pouze "except:", vždy uveď kterého typu výjimky se to týká. Například v tvém případě by to bylo "except TypeError:". Je to proto, že i stisknutí Ctrl+C vyvolá výjimku a ty bys ji takhle odchytil, což není to co ty chceš a program by pak nešel tímto způsobem přerušit. I kdybys nevěděl, který typ chyby použít, uveď alespoň "except Exception:". Exception je třída odvozená od BaseException, ale KeyboardInterrupt je odvozen přímo od BaseException a ne od Exception, tudíž odchytávání Exception nezachytí KeyboardInterrupt. Asi jsem to napsal dost nepřehledně, takže doufám, že jsem tě tím ještě více nezmátl.

Nahlásit jako SPAM
IP: 212.24.152.–
koumes21
~ Anonymní uživatel
18 příspěvků
23. 2. 2009   #9
-
0
-

Ještě se omlouvám, teď jsem si přečetl, že ten kód v tom odkazu nebude v tvém případě fungovat, protože dokáže přerušit pouze operaci, která je zaseklá v kódu Pythonu, ale ne tu, která je zaseklá v nějakém kódu na nižší úrovni, což je právě tvůj případ. Ještě jednou se tedy omlouvám za falešnou naději.

Nahlásit jako SPAM
IP: 212.24.152.–
Fstekly maltezak
~ Anonymní uživatel
4 příspěvky
24. 2. 2009   #10
-
0
-

Děkuji za vysvětlení prvního kódu.

koumes21 napsal:
Operační systém většinou povoluje zabití vlákna, jenže problém je, že vlákno nedostane příležitost po sobě uklidit. Některé programovací jazyky dají programátorovi příležitost vlákno zabít, Python ovšem nikoliv, protože je jaksi zaměřen na začátečníky a nechce jim dávat do rukou zbraň hromadného ničení, kterou neumí ovládat...



Nebylo by tedy nějak možné naimportovat do Pythonu nějakou knihovnu z jiného jazyka, která by toto umožnila? Nebo něco v tomto smyslu? ... Pokud ne, tak budu muset přepracovat celý program a nebo vyloučit možnost umocňování, protože ona je 99%-ní příčinnou problémů. To ovšem dosti znevýhodní program jako celek. Tento program píši už podruhé. První verze Fungovala tak že, vrozce byly umístěné do samostatných souborý které se pak souštěli. Tam nebyl žádný problém je ukončit. Stačilo zavolat "os.system('taskkill /t /f /im "konkretni_vzorec.py"') po určité době. (např. 5 sekund). Od tohoto jsem, ale ustoupil abych celý program zrychlil a navrhl ho tak že už nebude používat žádné mnou vytvořené tempy. Evidentně jsem si vybral špatný programovací jazyk pro svůj problém.

Nahlásit jako SPAM
IP: 78.136.155.–
rainbof0
Newbie
13. 3. 2009   #11
-
0
-

spis bych to videl tak ze si budes muset ten "vypocetni" modul udelat v jinem jazyce a pak si ho pripojit.

Nahlásit jako SPAM
IP: 81.90.165.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 18 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý