Domanda

Sto cercando di creare un MainObject che è un lavaggio come un servizio DBus. Questo MainObject deve sempre rimanere sensibili ad altri oggetti / processi e per questo non-blocking, anche durante l'elaborazione dei suoi elementi. per questo motivo gli elementi vengono elaborati in un thread separato uno dopo l'altro (coda di stile). È possibile aggiungere elementi alla MainObject tramite DBus o riga di comando. Ho semplificato il campione (senza dbus, nessuna riga di comando) per mostrare il mio problema.

Il mio problema è, che se riattivare 'tt.join ()' l'applicazione funziona come previsto, ma si blocca ad altri processi. Non c'è da stupirsi, tt.join rende l'attesa applicazione fino alla discussione separata ha terminato il suo lavoro. D'altra parte, se 'tt.join ()' rimane disattivata, l'applicazione non blocca a eventi dbus esterni, ma non arriva mai a 'ThreadTest fatto!' (Vedi prodotto in termini reali)

Quello che voglio è, la mia uscita previsto, ma le applicazioni dovrebbe rimanere reattivo.

#!/usr/bin/python2.5

import gobject
import threading
import re
import time

class ThreadTest(threading.Thread):

  def __init__(self):
    threading.Thread.__init__ (self)    
    print '  ThreadTest created!'

  def run(self):
    print '  ThreadTest running ...'
    time.sleep(1)
    print '  ThreadTest done!'
    return True

class MainObject():
  def __init__(self):
    self.timer = gobject.timeout_add(1000, self.update)
    self.loop  = gobject.MainLoop()
    print 'MainObject created!'

  def update(self):
    print 'MainObject updating ...'
    if self.check_running() == False:
      tt = ThreadTest()
      tt.start()
      #tt.join()
    return True

  def check_running(self):
    running = False
    expr = re.compile('ThreadTest')
    for threadstr in threading.enumerate():
      matches = expr.findall(str(threadstr))
      if matches:
        running = True
    return running  


mo = MainObject()
mo.loop.run()

output previsto:

MainObject created!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
  ThreadTest done!

produzione reale:

MainObject created!
MainObject updating ...
  ThreadTest created!
  ThreadTest running ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
MainObject updating ...
È stato utile?

Soluzione

Gli attacchi GObject per impostazione predefinita non sono multithread-aware. Si prega di provare a fare quanto segue subito dopo aver importato gobject:

gobject.threads_init()

Altri suggerimenti

Filati in pitone può essere una trappola - è un problema aperto, in realtà. Il problema principale è la GIL -. Global Interpreter Lock di Python

Uno dei modi hanno inventato per superare questo è il modulo "multiprocessing" (di nuovo in Python 2.6) - conserva l'interfaccia "threading", ma in realtà esegue il codice in un processo separato: Si potrebbe provare a sostituire finite htreading da multiprocessing - ma: fare tutto l'interazione dbus, GUI, ecc .. su un principale "filo" - (vale a dire un unico processo) - ed i dati commerciali con i sub-proccesses (stringhe, liste, dizionari, ecc) ... che avrebbe funzionato bene.

Inoltre, non riesco a capire il motivo per cui tutto questo regexp Voodo solo per controllare se una data stringa è presente sul valore di ritorno di threading.enumerate ?? Python ha anche l'operatore "in" (in modo che non hanno nemmeno bisogno di usare l'indice della str, o trovare metodi):

è possibile sostituire quello intero metodo check_running per:

def check_running(self):
    return 'ThreadTest' in str(threading.enumerate())
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top