program freezes after thread ends

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Feanor
User
Beiträge: 7
Registriert: Montag 18. August 2008, 18:16

I hab versucht ein Programm zu schreiben, dass eine Datei übers Netzwerk schickt. Jetzt habe ich aber das Problem , dass nachdem das Programm vom Send_Thread zurückkehrt stecken bleibt. Dies geschieht hauptsächlich wenn die Dateien etwas größer werden. kleine Textdateien funktionieren einwandfrei. ich weiß nicht mehr weiter.

testet hab ich das Programm mit "nc -l -p 40000" Daten kommen immer vollständig an nur das Programm hängt bei " print "nach" "

:~$ python --version
Python 2.5.2

Code: Alles auswählen

#! /usr/bin/env python
import socket
import pygtk
pygtk.require('2.0')
import gtk,gobject,os,math
from threading import Thread

class p2p():

	def main(self):
		gtk.main()	

	def __init__(self):
		gtk.gdk.threads_init()
		#Widgets anlegen und initialisieren
		self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.notebook=gtk.Notebook()
		self.file_chooser=gtk.FileChooserButton("select a file")
		self.send_button=gtk.Button("send file")
		self.address=gtk.TextView()
		self.address.get_buffer().set_text("localhost:40000")
		self.box_send=gtk.VBox(False,0)	
		self.box_recieve=gtk.VBox(False,0)

		self.tree_send=gtk.TreeStore(str,str)
		self.tree_send.append(None,["test","50%"])

		self.tv=gtk.TreeView(self.tree_send)	
	
		self.ip_column = gtk.TreeViewColumn("IP")
		self.progress_column = gtk.TreeViewColumn("Progress")

		self.tv.append_column(self.ip_column)
		self.tv.append_column(self.progress_column)
		
		self.ip_cell = gtk.CellRendererText()
		self.progress_cell = gtk.CellRendererText()

		self.ip_column.pack_start(self.ip_cell,True)
		self.progress_column.pack_start(self.progress_cell,True)

		self.ip_column.set_attributes(self.ip_cell, text=0)
		self.progress_column.set_attributes(self.progress_cell, text=1)

		#signale binden
		self.window.connect("delete_event",self.destroy)
		self.window.connect("destroy",self.destroy)
		self.send_button.connect("clicked",self.on_send_clicked)

		#Hinzufuegen des Notebooks ins das Fenster
		self.window.add(self.notebook)

		#Inhalt des send Tabs
		self.box_send.pack_start(self.file_chooser)
		self.box_send.pack_start(self.address)
		self.box_send.pack_start(self.send_button)
		self.box_send.pack_start(self.tv)

		#Inhalt des recieve Tabs

		#Hinzufuegen der Seiten zum Notebook
		self.notebook.append_page(self.box_send,gtk.Label("send"))
		self.notebook.append_page(self.box_recieve,gtk.Label("recieve"))
		
		#Alles anzeigen
		self.window.show_all()

	def destroy(self, widget, data=None):
		gtk.main_quit()
	
	def on_send_clicked(self,send_button):
		ip,port = self.address.get_buffer().get_text(*self.address.get_buffer().get_bounds()).split(":")
		ct = Send_Thread(ip,int(port),self.file_chooser.get_filename(),self)
		print "vor"			
		print ct.start()
		print "nach"
		del ct

	def recieve(self,port):
		s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		s.bind(('',port))
		s.listen(5)		
		while 1:
			conn,addr = s.accept()
			print addr
			data=""
			while True:
				byte = conn.recv(1)
				if not byte:
					break
				else:
					data += byte
			print data
			conn.close()
		
class Send_Thread(Thread):
	def __init__(self,ip,port,url,gui):
		Thread.__init__(self)
		self.ip=ip
		self.port=port
		self.url=url
		self.gui=gui
	def run(self):
		s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		f=file(self.url,'r')
		s.connect((self.ip,self.port))
		print "Uebertragung gestartet"
		gtk.gdk.threads_leave()
		tv_entry = self.gui.tree_send.append(None,[self.ip,"0"])
		gtk.gdk.threads_enter()
		packets_send=0
		old_progress = "0"
		while True:
			data=f.read(512)
			if data == "":
				print "Uebertragung fertig"
				break
			s.send(data)
			packets_send+=1
			
			if old_progress != str((packets_send*100)/int(math.ceil(os.path.getsize(self.url)/512.0))):
				gtk.gdk.threads_leave()
				gobject.idle_add(self.gui.tree_send.set_value,tv_entry,1,str((packets_send*100)/int(math.ceil(os.path.getsize(self.url)/512.0))))
				gtk.gdk.threads_enter()
				print str((packets_send*100)/int(math.ceil(os.path.getsize(self.url)/512.0)))
			old_progress = str((packets_send*100)/int(math.ceil(os.path.getsize(self.url)/512.0)))
			
		print f.close()
		print s.close()
		print "end"
		
x = p2p()
x.main()
mfg Feanor[/code]
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Bist du dir sicher das du das:

Code: Alles auswählen

gtk.gdk.threads_leave()
tv_entry = self.gui.tree_send.append(None,[self.ip,"0"])
gtk.gdk.threads_enter()
Nicht umgekehrt meinst? ;)

Am besten verwendest du gleich einen context manager:
http://29a.ch/git/gitweb.cgi?p=x29a;a=b ... master#l77
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Feanor
User
Beiträge: 7
Registriert: Montag 18. August 2008, 18:16

Danke für die schnelle Antwort

kann mir wer kurz erklären was "gtk.gdk.threads_enter()" genau macht?

mfg Feanor
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Feanor hat geschrieben:Danke für die schnelle Antwort

kann mir wer kurz erklären was "gtk.gdk.threads_enter()" genau macht?

mfg Feanor
Das steht in der Dokumentation und wenn du es noch genauer wissen willst im gtk source code.
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Antworten