Pages : 1
#1 Le 02/05/2006, à 18:10
- Anbreizh
[Résolu] Threads+Python
Bonjour a tous !
Alors la je dois avoué que je vois pas comment faire. Je suis en train d'essayé de mettre en place plusieur threads dans mon programme. Je veux en faire faire un Thread pour L'interface graphique, et un autre pour les commandes gourmande (Copie de fichiers .... )
Je l'ai mis en place, ca fonctionnes sauf un gros probleme : Le second thread se lance que le premier est fini, uniquement a ce moment la ! Je n'arrive pas a comprendre pourquoi.
Voici le code :
class MakeGui:
def on_extract_clicked(self,gui):
self.gui.get_widget( "extractwindow" ).show()
self.window = self.gui.get_widget( "extractbar" )
self.label = self.gui.get_widget( "etatlabel" )
number = random.randint(0,100)
temp = "/tmp/cdrom"+str(number)
t = Thread(self.path,temp)
self.window.pulse()
self.label.set_text("Copie du DVD sur le disque dur")
t.start()
class Thread(threading.Thread):
def __init__ (self, chemin, temp):
threading.Thread.__init__(self)
self.chemin = chemin
self.temp = temp
def run (self):
print "copie lancé"
shutil.copytree(self.chemin,self.temp)
print "copie fini"
J'ai enlevé les parties inutiles, c'est un programme qui se base sur Glade pour l'interface graphique si ca peut aidé.
Merci d'avance !
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#2 Le 02/05/2006, à 23:59
- gene69
Re : [Résolu] Threads+Python
ben je connais pas du tout ce language là mais je ne vois d'un seul appel du constructeur t = Thread(self.path,temp) dans ce cas, ya pas de miracle, surtout que . tu appelles le tout à la fin...
Lorqu'on code des thread, je crois que le mieux et d'avoir n+1 thread utiles.
le thread "pere" qui boucle/ attent que touts les fils aient terminé
les fils qui bossent...
m'enfin je dis sans doute une bétise...
Quand le berger est lâche, le loup chie de la laine.
A (draft) guide to UFO Alien-Invasion
Hors ligne
#3 Le 03/05/2006, à 09:02
- Anbreizh
Re : [Résolu] Threads+Python
Merci du conseil, je vais tester de mettre sa en place !
Je pense que c'est une bonne idée
Merci
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#4 Le 03/05/2006, à 09:15
- ale
Re : [Résolu] Threads+Python
Lancer des threads est un chose, les gérer et les synchroniser en est une autre. C'est ce que fait le module Queue.
#5 Le 03/05/2006, à 09:26
- Anbreizh
Re : [Résolu] Threads+Python
J'etais justement en train de me posé la question pour les gerer !
Merci des conseils ! Je vais regarder sa
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#6 Le 03/05/2006, à 13:56
- Anbreizh
Re : [Résolu] Threads+Python
Alors j'ai chercher comme mettre sa en place, je suis parti dans l'idée de faire un Thread pour le GUI et des Thread pour les operations lourdes.
Le probleme c'est que je vois pas comment mettre sa en place. J'ai coder les deux thread, lance le 1er ne pose pas probleme, c'est le second, qui intervient juste quand l'utilisateur le demande dans l'interface graphique, il faut donc qu'il attende jusque la.
Si vous savais comment mettre sa en place, car j'ai chercher mais je n'arrive pas a comprendre comme coder plusieur threads.
Les deux thread a lancé ici sont : MakeGui pour l'interface et Extract qui copy des fichiers sur le DD
Merci D'avance !
Ps : Le code :
import psyco
import gobject
import Queue
import pymedia.removable.cd as cd
import dbus
import gnome.ui
import gtk.glade
import random
import shutil
import threading
import sys
import psyco
APPNAME="GnomeShrink"
APPVERSION="0.1"
def simpleErrorMessageDialog(message):
d = gtk.MessageDialog(None,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_CLOSE,message)
d.run()
d.destroy()
class MakeGui (threading.Thread):
def __init__( self ):
threading.Thread.__init__(self)
gnome.init( APPNAME, APPVERSION )
self.gui = gtk.glade.XML( "gnomeshrink.glade" )
self.gui.get_widget( "mainwindow" ).connect("delete_event", self.destroy)
self.gui.signal_autoconnect( self )
self.titlemodel = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.soundmodel = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
self.defview("titletreeview",self.titlemodel,"Titre","Taille")
self.defview("soundtreeview",self.soundmodel,"Langue", "Taille")
self.inputlist()
self.outputlist()
def run (self):
pass
def destroy( self, widget, data=None ):
gtk.main_quit()
sys.exit()
def on_quit1_activate (self, gui):
gtk.main_quit()
def defview (self, tree, model, name1, name2):
self.view = self.gui.get_widget(tree)
self.model = model
self.view.set_model(self.model)
self.renderer = gtk.CellRendererText()
self.column = gtk.TreeViewColumn(name1, self.renderer, text=1)
self.column2 = gtk.TreeViewColumn(name2, self.renderer, text=2)
self.view.append_column(self.column)
self.view.append_column(self.column2)
def inputlist(self):
i = 0
self.dev = {}
inputlist = self.gui.get_widget( "inputlist" )
self.bus = dbus.SystemBus()
self.hal_object = self.bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
devices = self.hal_object.FindDeviceByCapability ("storage.cdrom", dbus_interface='org.freedesktop.Hal.Manager')
for device in devices:
device_manager = self.bus.get_object('org.freedesktop.Hal', device)
dvd = device_manager.GetPropertyBoolean("storage.cdrom.dvd", dbus_interface='org.freedesktop.Hal.Device')
if dvd == True:
device = device_manager.GetPropertyString("block.device", dbus_interface='org.freedesktop.Hal.Device')
text = device_manager.GetPropertyString("info.product", dbus_interface='org.freedesktop.Hal.Device')
self.dev[text] = i
i += 1
self.updatelist(text, "inputlist")
inputlist.connect( 'changed', self.changed_cb )
inputlist.set_active( 0 )
def outputlist(self):
liste = ["Image disque","Fichier Xvid"]
outputlist = self.gui.get_widget( "outputlist" )
a = len(liste)
b = 0
while a > b:
outputlist.insert_text(0, liste[b])
b += 1
if b:
outputlist.connect( 'changed', self.changed_cb )
outputlist.set_active( 0 )
def changed_cb( self, list ):
model = list.get_model()
index = list.get_active()
def updatelist(self, text, widget):
liste = self.gui.get_widget( widget )
liste.insert_text(0, text)
def on_extract_clicked(self,gui):
self.gui.get_widget( "extractwindow" ).show()
self.window = self.gui.get_widget( "extractbar" )
self.label = self.gui.get_widget( "etatlabel" )
number = random.randint(0,100)
self.temp = "/tmp/cdrom"+str(number)
self.window.pulse()
self.label.set_text("Copie du DVD sur le disque dur")
self.a = 0
def extractsound (filein, fileout):
dm = muxer.Demuxer( filein.split( '.' )[ -1 ].lower() )
f= open( inFile, 'rb' )
fw= open( outFile, 'wb' )
s= f.read( 400000 )
r= dm.parse( s )
v= filter( lambda x: x[ 'type' ]== muxer.CODEC_TYPE_AUDIO, dm.streams )
a_id= v[ 0 ][ 'index' ]
print 'Un flux audio trouvé au %d index: ' % a_id
while len( s )> 0:
for fr in r:
if fr[ 0 ]== a_id:
fw.write( fr[ 1 ] )
r= dm.parse( s )
def on_refresh_clicked(self, gui):
z = 0
x = 0
self.soundmodel.clear()
self.titlemodel.clear()
device = self.gui.get_widget( "inputlist" ).get_active_text()
cdrom = self.dev[device]
cd.init()
c = cd.CD(cdrom)
etat = c.isReady()
if etat == 1:
props = c.getProperties()
if props[ 'type' ]== 'DVD':
title = props['titles']
label = props['label']
self.path = c.getPathName()
iter = self.titlemodel.insert_before(None, None)
self.titlemodel.set_value(iter, 1, label)
for a in title:
w = 1
choix = title[z]
self.iter = self.titlemodel.insert_before(None, None)
self.titlemodel.set_value(self.iter, 1, choix)
opens = c.open(choix)
details = opens.getProperties()
taille = details["length"]
self.itertaille = self.titlemodel.insert_before(None, None)
self.titlemodel.set_value(self.itertaille, 2, str(taille)+" Mo")
chapitre = details["chapters"]
for b in chapitre:
chap = "Chapitre %d" % w
new_iter = self.titlemodel.insert_before(self.iter, None)
self.titlemodel.set_value(new_iter, 1, chap)
w +=1
z += 1
stream = details["audio_streams"]
tuples = len(stream)
while x < tuples: # Recupere juste les données audio au dernier Title
audio = stream[x]
language = audio['language']
#for a in language:
self.iter = self.soundmodel.insert_before(None, None)
self.soundmodel.set_value(self.iter, 1, language)
format = audio["format"]
new_iter = self.soundmodel.insert_before(self.iter, None)
self.soundmodel.set_value(new_iter, 1, format)
x += 1
else:
pass
cd.quit()
if etat == 0:
simpleErrorMessageDialog("Le periphérique n'est pas prêt ou ne contient aucun media")
class Extract(threading.Thread):
def __init__ (self):
threading.Thread.__init__(self)
threading.Condition(self.a)
def run (self):
print "copie lancé"
shutil.copytree(self.path,self.temp)
print "copie fini"
if __name__ == "__main__":
gui = MakeGui()
ex = Extract()
gui.start()
ex.start()
gtk.main()
Merci d'avance !
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#7 Le 03/05/2006, à 14:58
- gene69
Re : [Résolu] Threads+Python
Personnellement je comprend rien au code ... et comme il est largement commenté c'est encore plus dur.
Je ne peut donc baser ma réponce que sur ce que tu racontes avant. Il me semble que ton thread de copy doit commencer à s'executer qu'apres une action determinée sur l'interface. Jusque là j'ai juste?
Dans ce cas tu peux te contenter de mettre lancer ton thread quand ton utilisateur clique sur le bouton. En théorie ça se lance de partout un thread. Comme ça tu es sur qu'il démare au bon moment.
Ensuite il faut récuperer l'etat d'avancement de ton thread... et le message d'erreur.
En C j'aurai di pthread_join() qui aurai mis en pause le thread qui appelle join et récupere le message d'erreur.
Pour connaitre l'avancement j'aurrai mi une zone critique avec un mutex que se partagent le thread de copie et le thread de controle.
note est ce que je comprend bien que:
threading.Thread.__init__(self) /*ça lance le thread ()*/
s= f.read( 400000 ) /*tu lis 400000 octects d'un coup? tu es sur que c'est la meilleure tailles? en C chez moi c'est 4096*/
bon et puis le reste c'est encore un peu obscur
Il me semble que multiplier le nombre de thread n'est pas une bonne idee si on cherche la performance, puisqu'on perd du temps avec les changements de contextes.
Mais c'est vrai que ça améliore l'interactivité.
Quand le berger est lâche, le loup chie de la laine.
A (draft) guide to UFO Alien-Invasion
Hors ligne
#8 Le 03/05/2006, à 15:08
- Anbreizh
Re : [Résolu] Threads+Python
C'est bien ca que je veux faire. Je ne voulais pas au depart crée plusieur thread mais vu que je copie des fichier de plusieur Go, l'interface ne suit pas autrement.
Je vais regarder tes informations et le tester
Merci beaucoup
Ps : Je vais commenté mon code
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#9 Le 03/05/2006, à 16:30
- Lightning Flik
Re : [Résolu] Threads+Python
Pour le problème de départ (le 2eme thread qui se lance uniquement lorsque le premier se termine), il me semble qu'il fallait lancer :
gtk.gdk.threads_init()
avant de créer ta fenêtre
Aussi, il y a quelques problèmes avec les threads en python, apparemment ce ne sont pas encore des vrais threads si j'ai tout bien compris. Enfin en tous cas s'il y a certaines opérations bloquantes (par exemple raw_input), le contrôle n'est pas rendu aux autres threads pendant ce temps.
Je te conseille de lire ceci : http://linuxgazette.net/107/pai.html
Hors ligne
#10 Le 03/05/2006, à 16:49
- Anbreizh
Re : [Résolu] Threads+Python
Merci beaucoup ! Je pense que cette commande vas me reglé le probleme ! Je teste et je te dis
Merci Beaucoup
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
#11 Le 03/05/2006, à 16:56
- Anbreizh
Re : [Résolu] Threads+Python
Nikel !
Sa marche ! Je comprenais pas pourquoi le threads voulais pas ce lancé !
Vraiment merci beaucoup
"C'est le devoir de chaque homme de rendre au monde au moins autant qu'il en a reçu" Albert Einstein
Pour votre webcam : http://projet.jbtheou.fr
Mon site web (Mathématique, physique, science et service de publication ) http://jbtheou.fr
Hors ligne
Pages : 1