【问题标题】:threading.Thread not working but _thread doesthreading.Thread 不工作,但 _thread 工作
【发布时间】:2021-05-14 18:05:42
【问题描述】:

我有一些使用 wxPython 创建 gui 的旧版 python 2.7 代码。 gui 代码使用_thread.start_new_thread 来启动从另一个模块导入的函数。我们正在将此代码转换为 python 3.9,我想用threading.Thread 替换_thread,这样我就可以使用thread.excepthook。但是,当我将 _thread 替换为 threading.Thread 时,我的代码就会挂起。

例如我有:

import _thread
import custom_module

_thread.start_new_thread(custom_module.go, (arg1, arg2))

custom_module 有一个执行的函数 go。这在 Python 3.9 中都可以正常工作,但我正在尝试使用 threading.excepthook,所以我尝试将其替换为:

import threading
import custom_module

threading.Thread(target=custom_module.go, args=(arg1, arg2)).start()

但是当我的代码到达线程时它只是挂起。

_threadthreading 之间是否存在一些差异会导致线程挂在 threading 而不是 _thread

另外,在 Python 2.7 中,我使用 sys.excepthook 来管理线程中发生的异常,但这不再有效。当线程中发生异常时,线程就结束了。有什么想法吗?

================================================ ================== 所以看起来问题不在于 threading.Thread 不起作用。我能够在 custom_module.go 函数的开头执行打印语句。它实际上挂在 logger.info 语句上,用于在主程序中得到证实的记录器。

def init_logger():
    """Initialize."""
    logger = logging.getLogger('FDS')
    logger.setLevel('INFO')
    logging.Formatter.converter = time.gmtime

    formatter = logging.Formatter('%(asctime)s.%(msecs)03d | %(levelname)-8s |' +
                                  ' %(name)s | %(message)s',
                                  datefmt='%Y/%j-%H:%M:%S')

    # set up log buffers (will flush into log file & GUI once started)
    mh_file = logging.handlers.MemoryHandler(capacity=1000, flushLevel='DEBUG')
    mh_file.setFormatter(formatter)
    logger.addHandler(mh_file)

    mh_gui = logging.handlers.MemoryHandler(capacity=1000, flushLevel='DEBUG')
    mh_gui.setFormatter(formatter)
    logger.addHandler(mh_gui)

    logger.info('=' * 80)
    logger.info('Starting FDS - Release ' + __version__ + '...')

    # create application
    logger.info('Building GUI...')
    app = wx.App(False)
    logger.debug('FDS GUI application created.', extra={'same_line':True})

我的代码挂了

def go()
    logger.info('Performing input validation...')
    .
    .
    .

【问题讨论】:

  • 您确定它肯定挂在线程调用上,而不是在custom_module.go 内部吗?可以分享go函数吗?
  • 请提供minimal reproducible example。作为这里的新用户,也可以使用tour 并阅读How to Ask。顺便说一句:同时更改两件事(Python 版本、线程支持)也是需要重新考虑的事情。
  • @KacperFloriański 我以为我已经确定它挂在线程调用上,因为我在 go 函数的开头发生了日志记录。但是当我首先放置一个简单的打印语句时,我了解到它挂在我的记录器上。看起来 _thread 允许我使用我的记录器(在我的主线程中得到证实),而 threading.Thread 不允许。
  • 是的,我们需要查看您的记录器和其余代码以确定哪里出了问题(重现) - 除非您从现在开始可以自行调试,因为线程很好:)跨度>

标签: python multithreading python-multithreading


【解决方案1】:

我想通了。我用一个我以前用来覆盖 sys.excepthook 的函数覆盖了 threading.excepthook 并且我没有更改函数的参数(假设参数将保持不变)。但是,在 threading.excepthook 覆盖函数中,您只能提供一个参数 (https://docs.python.org/3/library/threading.html)。当我修复我的线程能够正常工作并正确处理错误时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 2021-11-28
    • 2018-12-19
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多