Search code examples
pythonmultithreadingloopssleepblocking

Multithreading python application hangs while running its threads


I am trying to create a MainObject which is availible as a DBus service. This MainObject should always stay responsive to other objects/processes and for this non-blocking even while processing its items. for that reason items are processed in a seperate thread one after another (queue-style). You can add items to the MainObject via DBus or CommandLine. I simplified the sample (no dbus, no commandline) to show my problem.

My problem is, that if i reenable 'tt.join()' the application works as expected, but it is blocking to other processes. No wonder, tt.join makes the application wait until the seperate Thread has finished its work. On the other hand, if 'tt.join()' stays disabled, the application does not block to external dbus events, but never comes to 'ThreadTest done!' (look at real output)

What i want is, my expected output but the applications should stay responsive.

#!/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()

expected output:

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!

real output:

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 ...

Solution

  • The gobject bindings by default aren't multithread-aware. Please try to do the following just after you have imported gobject:

    gobject.threads_init()