gobject idle funktioniert nicht so richtig

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ok, das mit dem Progress Bar war jetzt ein sehr blödes Beispiel, den im Prinzip greife ich ja nicht mal auf den GUI zu, sondern er lädt nur Dateien auf einen Server, ich starte den Thread so:

Code: Alles auswählen

thread=my_thread()
thread.start()
ist das falsch?


edit: mir ist aufgefallen, wenn ich zu Testzwecken einfach mal diese Thread in genau mein Programm einbaue also:

Code: Alles auswählen

class my_thread(threading.Thread):
	def __init__(self):
		threading.Thread.__init__(self)
		
	def run(self):
		i=0
		for i in range(5):
			time.sleep(1)
			i=i+1
			print i
		print "fertig"

class programm:
.........
......
....
	starte_thread=my_thread()
	starte_thread.start()

Wenn ich diesen Thread starte, passiert nichts... Erst wenn ich einmal strg+c drücke, dann laufen die Zahlen, an was kann das liegen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs, gewöhn dir an funktionsfähige Minimalbeispiele zu posten. Ich werde deinen Code nicht mehr erweitern bis es geht, weil es dann nicht reproduzierbar ist:

Code: Alles auswählen

import threading, time

class my_thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        i=0
        for i in range(5):
            time.sleep(1)
            i=i+1
            print i
        print "fertig"

starte_thread=my_thread()
starte_thread.start()
Funktioniert hier nämlich problemlos.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Sry, also es klappt jetzt, mein Problem war, das ich

Code: Alles auswählen

gobject.threads_init()
nicht benutzt habe. Wenn man einen Thread hat der nicht viel machen soll, geht es auch ohne. Aber wenn der Thread länger braucht, um etwas zu machen, gibt es unter GTK große Probleme, also er führt den Thread dann überhaupt nicht aus. Damit geht nun alles problemlos, noch mal danke für den ganzen Stress mit mir kompliziertem Jungen :D

Jetzt stehe ich leider vor einem neuen Problem, und zwar, bekomme, ich wenn ich diese Funktion in einem Thread öfters hintereinander aufrufe, einen Speicherzugriffsfehler, aber sehr sporadisch. Hier die Funktion:


Code: Alles auswählen

	def homemake_list(self, dname=None):
		if not dname:
			self.homedirname=os.path.expanduser("~")
		else:
			self.homedirname=os.path.abspath(dname)
		files=[f for f in os.listdir(self.homedirname) if f[0] <> "."]
		filestat=os.stat(self.homedirname)
		self.homeliststore.clear()
		self.homeliststore.append(["..", filestat.st_size, oct(stat.S_IMODE(filestat.st_mode)), time.ctime(filestat.st_mtime)])
		for f in files:
			filename=os.path.join(self.homedirname, f)
			filestat=os.stat(filename)
			self.homeliststore.append([f, filestat.st_size, oct(stat.S_IMODE(filestat.st_mode)), time.ctime(filestat.st_mtime)])
Den dazugehörigen TreeView mache ich so:

Code: Alles auswählen

		self.homeliststore=gtk.ListStore(str, str, str, str)
		self.hometreeview=gtk.TreeView(self.homeliststore)
		self.hometreeview.connect("row-activated", self.homeopen)
		self.ftp_menu_client=self.xml.get_widget("ftp_menu_client")
		self.hometreeview.connect_object("button-press-event", self.homerigth_click, self.ftp_menu_client)
		self.hometreeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

		self.hometvcolumn=[]
		self.hometvcolumn.append(" ")
		self.hometvcolumn.append(gtk.TreeViewColumn("Name"))
		self.hometvcolumn.append(gtk.TreeViewColumn("Size"))
		self.hometvcolumn.append(gtk.TreeViewColumn("Mode"))
		self.hometvcolumn.append(gtk.TreeViewColumn("Last Changed"))

		for i in range(1, 5):
			self.hometreeview.append_column(self.hometvcolumn[i])
			
		self.homecell = gtk.CellRendererText()
		for i in range(1,5):
			self.hometvcolumn[i].pack_start(self.homecell, True)
			
		for i in range(1,5):
			self.hometvcolumn[i].set_attributes(self.homecell, text=i-1)
			
		self.vbox17=self.xml.get_widget("vbox17")
		self.homescrolledwindow1=gtk.ScrolledWindow()
		self.homescrolledwindow1.add(self.hometreeview)
		self.vbox17.pack_start(self.homescrolledwindow1)
(self.xml ist die glade Datei)

Den Thread rufe ich so auf:

Code: Alles auswählen

		gobject.threads_init()
		thread=cl_act_thread(self.homemake_list, self.progressbar2)
		thread.start()
und der Thread sieht dann so aus:

Code: Alles auswählen

class cl_act_thread(threading.Thread):
	def __init__(self, homemake, progressbar):
		threading.Thread.__init__(self)
		self.homemake_list=homemake
		self.progressbar=progressbar
		
	def run(self):
		self.end_status=0
		
		def progress(progress):
			progress.pulse()
			if self.end_status==0:
				return True
			else:
				progress.set_fraction(0)
				progress.set_fraction(0.2)
				return False
		
		gobject.timeout_add(50, progress, self.progressbar)
		self.homemake_list()
		time.sleep(0.5)
		self.end_status=1
Tut mir leid, dass das jetzt alles so einzeln ist. Aber im Programm ist das leider alles sehr verteilt. Die Funktionen so, ohne alles drum und dran, habe ich noch nicht ausprobiert.

Ich habe im Internet schon Beiträge so einem Fehler von Firefox gefunden, bei dem es auch um Speicherzugriffsfehler ging. Da hieß es, das es am GTK Theme liegen könnte, und das es ging, wenn man es als Root startet. Ging aber bei leider auch nicht. Dann habe ich Beiträge gefunden, das es am Ram liegen könnte. Kann aber eig. auch nicht sein, da der Fehler sonst auch bei andren Programmen gekommen wäre. Dann habe ich bei einem Beitrag gesehen, das jemand ein Programm geschrieben hat, bei dem es keine Speicherverwaltung gab. Was ist Speicherverwaltung bei Python? Habe von so etwas nie gehört.


Danke für jede Hilfe.

edit: Manchmal steht nur

bash: line 1: 7089 Speicherzugriffsfehler /usr/bin/python "datei.py"

und manchmal kommt

sys:1: GtkWarning: gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' failed
sys:1: Warning: g_object_set_property: assertion `G_IS_VALUE (value)' failed
sys:1: Warning: g_value_unset: assertion `G_IS_VALUE (value)' failed
bash: line 1: 7089 Speicherzugriffsfehler /usr/bin/python "datei.py"
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Dann habe ich bei einem Beitrag gesehen, das jemand ein Programm geschrieben hat, bei dem es keine Speicherverwaltung gab. Was ist Speicherverwaltung bei Python? Habe von so etwas nie gehört.
In Python ist die Speicherverwaltung automatisch, d.h. der Interpreter kümmert sich selbst darum, so viel Speicher wie nötig anzufordern und auch wieder freizugeben, wenn er nicht mehr nötig ist.
gugugs hat geschrieben:sys:1: GtkWarning: gtk_list_store_get_value: assertion `VALID_ITER (iter, list_store)' failed
sys:1: Warning: g_object_set_property: assertion `G_IS_VALUE (value)' failed
sys:1: Warning: g_value_unset: assertion `G_IS_VALUE (value)' failed
bash: line 1: 7089 Speicherzugriffsfehler /usr/bin/python "datei.py"
Könnte ein Bug in PyGTK oder GTK+ sein, da scheint die Speicherverwaltung des C-Codes fehlerhaft zu sein. Kannst also entweder mit den GTK-Leuten sprechen, dass die den Bug korrigieren oder dein Programm entwursteln, dass es den Bug nicht mehr hervorruft.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Habe es nun auf zwei anderen Rechnern getestet, da passiert nichts, läuft dort einwandfrei.

Zum Thema entwursteln. Was für Gründe können es sein, wenn so Fehler auftreten? Also allgemein? Kann dieser Speicherzugriffsfehler kommen, wenn man allgemein, einen unordentlichen Code schreibt, oder kann man das ein wenig, spezialisieren, das man sagen kann, es kommt von bestimmtem Kombinationen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Habe es nun auf zwei anderen Rechnern getestet, da passiert nichts, läuft dort einwandfrei.
GTK/PyGTK-Versionen geprüft? Vielleicht wurde das dort bereits ausgebessert oder es wird anderer Code verwendet (zum Beispiel unter einem anderen OS).
gugugs hat geschrieben:Also allgemein? Kann dieser Speicherzugriffsfehler kommen, wenn man allgemein, einen unordentlichen Code schreibt, oder kann man das ein wenig, spezialisieren, das man sagen kann, es kommt von bestimmtem Kombinationen?
Scher zu sagen, da ich mir deine 1000 Zeilen nicht wirklich antun will, aber die Closure die du da als Callback übergibst könnte eine Problemursache sein. Oder irgendetwas anderes. Jedenfalls sollte der Interpreter in Python nie mit einem solchen Fehler beendet werden, also ist da auf C-Ebene irgendein Bug aufgetreten.

(Sowas hatte ich damals auf wx unter Windows am laufenden Band und lustigerweise haben alle meine Versuche diese Bugs anders zu umgehen wiederrum zu anderen Bugs geführt. Ziemlich frustrierend. Ist aber schon eine Zeitlang her).
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Sollte man das jetzt möglichst unterlassen? Oder kann man da weiter machen, in der Hoffnung, das es wirklich an dem PC lag, mit dem es getestet wurde. Wie hoch ist denn die Wahrscheinlichkeit, das es am RAM an pygtk, oder am Code liegt? Also was trifft denn eher zu? Denn ich bin mir gar nicht so unsicher, das es an meinem RAM liegen könnte. Hab aber noch kein memtest gemacht.
aber die Closure die du da als Callback übergibst könnte eine Problemursache sein.
In wie fern?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Sollte man das jetzt möglichst unterlassen? Oder kann man da weiter machen, in der Hoffnung, das es wirklich an dem PC lag, mit dem es getestet wurde. Wie hoch ist denn die Wahrscheinlichkeit, das es am RAM an pygtk, oder am Code liegt?
Ähm, wer sollte das wissen?
gugugs hat geschrieben:
aber die Closure die du da als Callback übergibst könnte eine Problemursache sein.
In wie fern?
Vermutung. Closures sind ja in C eher nicht alltäglich, vielleicht räumt da also irgendein C-Code die Closure weg und versucht danach darauf zuzugreifen. Keine Ahnung, war nur eine Schätzung.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ich weiß leider nicht so genau, was Closures sind, beziehungsweise, was ich darunter verstehe. Wie kann ich das Problem am besten angehen?

edit: wenn ich das richtig verstehe, dann geht dieser Beitrag http://de.wikipedia.org/wiki/Closure in etwa in meine Richtung? Denn so ganz habe ich das noch nicht verstanden
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Iedit: wenn ich das richtig verstehe, dann geht dieser Beitrag http://de.wikipedia.org/wiki/Closure in etwa in meine Richtung? Denn so ganz habe ich das noch nicht verstanden
Eine Closure ist vereinfacht gesagt eine Funktion in einer Funktion.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ich verstehe irgendwie nicht so ganz, wo das bei mir vorkommt.
Schon mal Danke
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Ich verstehe irgendwie nicht so ganz, wo das bei mir vorkommt.
Die Funktion ``progress`` aus deinem Codeschnippsel.

Du solltest wirklich deinen Code strukturieren, wenn du sebst nicht mehr weißt wo was vorkommt. 1000 Zeilen sind nicht nur für uns zu viel, für dich sind die 1000 Zeilen eigentlich auch zu viel.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Das hatte ich leider schon geändert, daran liegt es leider nicht. Es ist wirklich komisch, denn dieser Fehler kommt wirklich auch dann, wenn ich nur diese Funktion benutze, die ich vorher gepostet habe, also kein andren Code. Und ich hab es an zwei verschiedenen PC's getestet, die beide die gleiche Python Version hatten, und bei dem einen gings, und bei dem anderen nicht. Es kommt auch wirklich seehr sporadisch vor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

PyGTK Versionen? GTK+ Versionen? OS?
Antworten