Ciao a tutti,

sto letteralmente diventando pazzo da qualche giorno su un problema di
possibile leak di ram, per definirlo meglio sto creando esempi che mi
portano altri problemi... ora vi parlo di uno di questi...

Vi propongo il codice seguente che usa le pygtk e dei weakref. Il
programmino crea delle istanze 'g' di un classe 'G' con una finestra
(gtk.Window) 'w' con 2 bottoni:

     1. il primo crea 'n' finestre e  un weakref per ciascuna per poterle
        poi uccidere
     2. il secondo bottone uccide le finestre

La stranezza è che il codice (abbastanza sempliciotto) funziona bene o molto 
male
a seconda:

  * del numero di finestre (passo il numero come unico argomento)
  * dell'interprete (2.5 o 2.6)

Con python2.5/Ubuntu 8.04 fino a 43 (quarantatré, che avrà mai?) finestre il
bottone 1 le crea ed il 2 le uccide. Già da 43 il bottone che
le dovrebbe uccidere non funziona più (ovvero i weakref non trovano
l'oggetto referenziato che in effetti esiste).

Su Ubuntu 9.04 ho sia python 2.5 che 2.6:

  2.5.2: stessi problemi
  2.6.2: nessun problema su ubuntu 9.04 (*)
  2.6.5: stessi problemi già con 3 finestre su ubuntu 10.04. 


Quando la finestra risulta incancellabile tramite il bottone kill, anche la
cancellazione tramite window-manager fallisce (AttributeError: G objectc has
no attribute 'title'). È come se la istanza 'g' sia stata resa monca nonostante
esista ancora una finestra con una callback attiva che referenzia (in senso
forte) l'istanza stessa ed il suo metodo 'delete_event_cb'. Chiamo 'monca'
questa istanza nel senso che:

  * la weakref non la vede più
  * la callback capisce che è una istanza di 'G' ma non ne vede l'attributo
    di istanza 'title'::

      Traceback (most recent call last):
        File "testd2_win.py", line 39, in clicked_cb
          if self.title:
      AttributeError: 'G' object has no attribute 'title'
  
Conto su un vostro input per non andare in corto...


sandro
*:-)



(*) se importo psutil [1] ho gli stessi probelmi...
[1] un modulo molto carino per avere le informazioni sui processi e la ram
    che darebbe ps: http://code.google.com/p/psutil/





-- 
Sandro Dentella  *:-)
http://sqlkit.argolinux.org        SQLkit home page - PyGTK/python/sqlalchemy
import os
import gc
import sys
import weakref
import gtk


class G(object):
    def __init__(self, title=''):
        self.windows = []
        self.title = title
        self.w = gtk.Window()
        self.w.set_title(title)
        self.h = gtk.HBox()
        self.kill_button = gtk.Button("kill")
        self.crea_button = gtk.Button(title and "Finestra %s" % title or "crea %s finestre" % n)
        self.w.add(self.h)
        self.h.add(self.crea_button)
        self.h.add(self.kill_button)
        self.w.show_all()
        self.w.connect('delete-event', self.delete_event_cb)
        self.kill_button.connect('clicked', self.clicked_cb)
        self.crea_button.connect('clicked', self.crea_molte_finestre)

    def delete_event_cb(self, win, ev=None):
        self.w.get_toplevel().destroy()
        del self.w

    def crea_molte_finestre(self, win, ev=None):
        if self.title:
            return
        self.wins = []
        for i in range(n):
            #r = G(title=str(i))
            r = weakref.ref(G(title=str(i)))
            self.windows += [r]

    def clicked_cb(self, win):
        if self.title:
            self.delete_event_cb(win)
        else:
            for g in self.windows:
                if g():
                    g().delete_event_cb(None, None)
                #if g:  # se non usi weakref
                #    g.delete_event_cb(None, None)
            self.windows = []
        

if __name__ == '__main__' :

    if len(sys.argv) == 2:
        n = int(sys.argv[1])
    else:
        n = 10
    G()
    try:
        gtk.main()
    except KeyboardInterrupt:
        sys.exit()
_______________________________________________
Python mailing list
Python@lists.python.it
http://lists.python.it/mailman/listinfo/python

Rispondere a