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

3
我正在尝试创建一个作为DBus服务可用的MainObject。这个MainObject应该始终对其他对象/进程保持响应,并且在处理其项时非阻塞,因此将项按顺序(队列方式)在单独的线程中处理。您可以通过DBus或CommandLine向MainObject添加项目。我简化了样本(没有dbus,没有commandline),以展示我的问题。
我的问题是,如果重新启用'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 ...

重复:https://dev59.com/o0rSa4cB1Zd3GeqPW4BE - ebo
2个回答

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

gobject.threads_init()

工作正常!谢谢!该死...我花了两天时间自己搜索这个 :D - user243877
你救了我一命,让我不再哭泣 :) - Miro Kropacek

0

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

他们发明的一种克服这个问题的方法是“multiprocessing”模块(在Python 2.6中新引入) - 它保留了“threading”接口,但实际上在单独的进程中运行代码: 你可以尝试用multiprocessing替换htreading - 但是:所有dbus交互、GUI等都要在一个主“线程”(即单个进程)上进行 - 并与子进程交换数据(字符串、列表、字典等)......那样就可以正常工作。

此外,我无法理解为什么要使用所有这些regexp Voodo来检查给定字符串是否存在于threading.enumerate的返回值中? Python甚至有“in”运算符(因此您甚至不必使用str的index或find方法):

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

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

谢谢你。有趣的背景信息,了解起来总是很好的! - user243877

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接