program freezes after thread ends

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

program freezes after thread ends

Beitragvon Feanor » Montag 20. Oktober 2008, 14:45

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:

Beitragvon veers » Montag 20. Oktober 2008, 15:53

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
My Website - 29a.ch
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Feanor
User
Beiträge: 7
Registriert: Montag 18. August 2008, 18:16

Beitragvon Feanor » Montag 20. Oktober 2008, 16: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:

Beitragvon veers » Montag 20. Oktober 2008, 17:04

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.
My Website - 29a.ch

"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder