多线程python应用程序在运行其线程时挂起

时间:2010-01-05 12:59:57

标签: python multithreading loops sleep blocking

我正在尝试创建一个可用作DBus服务的MainObject。此MainObject应始终对其他对象/进程保持响应,即使在处理其项目时也应保持此非阻塞状态。因此,项目一个接一个地在一个单独的线程中处理(队列样式)。您可以通过DBus或CommandLine将项添加到MainObject。我简化了示例(没有dbus,没有命令行)来显示我的问题。

我的问题是,如果我重新启用'tt.join()'应用程序按预期工作,但它阻止其他进程。难怪,tt.join让应用程序等到单独的Thread完成它的工作。另一方面,如果'tt.join()'保持禁用状态,则应用程序不会阻止外部dbus事件,但永远不会进入'ThreadTest完成!' (看实际输出)

我想要的是,我的预期输出,但应用程序应保持响应。

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

预期产出:

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!

实际输出:

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

2 个答案:

答案 0 :(得分:2)

默认情况下,gobject绑定不支持多线程。导入gobject后,请尝试执行以下操作:

gobject.threads_init()

答案 1 :(得分:0)

python中的线程可能是一个陷阱 - 实际上它是一个开放的问题。 主要问题是GIL - Python的全局解释器锁。

他们发明了解决这个问题的方法之一是“多处理”模块(python 2.6中的新功能) - 它保留了“线程”接口,但实际上是在一个单独的进程中运行代码: 您可以通过多处理尝试jsut替换htreading - 但是:在主“线程”上执行所有dbus交互,GUI等...(即单个进程) - 并使用子进程交换数据(字符串,列表,字典等)...这样可以正常工作。

另外,我无法弄清楚为什么所有这个regexp Voodo只是为了检查一个给定的字符串是否存在于threading.enumerate的返回值? Python甚至有“in”运算符(所以你甚至不必使用str的索引,或者找到方法):

您可以将整个check_running方法替换为:

def check_running(self):
    return 'ThreadTest' in str(threading.enumerate())