0

我正在编写一个提供 PySide UI 的程序。在其中,启动了一个线程,该线程设置了一系列应该在后台运行的功能,同时 UI 显示一个进度条。

我正在使用 Python 3 的 backportconcurrent.futures for Python 2.7 进行多线程处理。

UI 方法如下所示:

def doPostprocess(self):
    with ThreadPoolExecutor(max_workers=1) as executor:
        future = executor.submit(othermodule.func)
        while not future.done():
            QtGui.qApp.processEvents()
            self.progressbar.setValue(1)
            time.sleep(0.001)
    self.progressbar.hide()

这是我最小的othermodule.func样子:

def func():
    logger.info("Some informational message")
    time.sleep(15)
    print "And we are done here"

“我们在这里完成了”永远不会打印到标准输出,但future对象表示它在调用后立即完成logger.info

有趣的是:当我将调用更改为 时logger.debug,一切都按预期工作,即func记录、休眠 15 秒然后打印到标准输出,而主线程一直在更新其进度条。无论为应用程序设置什么日志级别,都会发生这种情况。

4

1 回答 1

1

您的记录器对象是如何配置的?可以为不同的日志级别配置不同的处理程序,它们可能会失败。请参阅https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging

另请查看此说明http://docs.python.org/2.7/library/logging.html?highlight=logging#thread-safety。可能是这样。

更新

您也可以尝试使用 catch-all 异常处理程序来查看线程内部发生了什么。像这样的一些事情:

def func():
    try:
        logger.info("Some informational message")
        time.sleep(15)
        print "And we are done here"
    except:
        print "We are interrupted"
        pprint.pprint(sys.exc_info())

更新2:

http://hg.python.org/cpython/file/af18829a7754/Lib/concurrent/futures/_base.py#l343所示。done()方法仅返回工作人员的状态并且不会引发异常。

exception()您可以检查未来方法是否存在异常。这也将删除不必要的异常处理func()

您的代码可能是(重新引发工作人员的异常):

def doPostprocess(self):
with ThreadPoolExecutor(max_workers=1) as executor:
    future = executor.submit(othermodule.func)
    while not future.done():
        QtGui.qApp.processEvents()
        self.progressbar.setValue(1)
        time.sleep(0.001)
    if future.exception() is not None:
        raise future.exception()
self.progressbar.hide()
于 2013-07-16T19:16:26.320 回答