3

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

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

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

#!/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 ...
4

2 回答 2

2

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

gobject.threads_init()
于 2010-01-05T15:30:52.687 回答
0

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

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

另外,我不明白为什么所有这些正则表达式 Voodo 只是为了检查给定字符串是否存在于 threading.enumerate 的返回值上?Python 甚至还有“in”运算符(因此您甚至不必使用 str 的索引或查找方法):

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

def check_running(self):
    return 'ThreadTest' in str(threading.enumerate())
于 2010-01-05T14:02:57.500 回答