Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 02/05/2006, à 19: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 03/05/2006, à 00: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, à 10: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, à 10: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, à 10: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 wink


"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, à 14: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, à 15: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 wink






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, à 16: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 wink


"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, à 17: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, à 17: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, à 17:56

Anbreizh

Re : [Résolu] Threads+Python

Nikel !
Sa marche ! Je comprenais pas pourquoi le threads voulais pas ce lancé !

Vraiment merci beaucoup wink


"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