【发布时间】:2019-08-13 03:01:53
【问题描述】:
我能找到的关于终止 Python 计时器线程的唯一其他问题是这个:how to terminate a timer thread in python,但这只是告诉我从阅读线程文档中已经知道的内容。
我正在用 Python 编写一个 GTK 应用程序。它通过 d-bus 与 HexChat 连接。因为当用户更改上下文(切换到不同的 IRC 通道或服务器窗口)时没有 D-bus 信号,所以我的原始设计一直等到用户以某种方式与 GUI 交互才能查看我们当前所处的上下文。这是需要切换的输入框,不能真正用于切换上下文,因为如果用户开始输入,则会发出更改的信号并将内容保存到旧的上下文中,这是不正确的行为。
为了解决这个问题,我决定使用线程定时器任务每 0.5 秒检查一次当前上下文是什么。线程函数检查当前上下文,更新类中的一个变量,然后以另一个 0.5 秒的延迟重新启动自身。这可以完美运行,并且速度足够快,可以跟上用户经常切换频道的速度。
但是,即使我将 TimerThread.cancel 添加到我的__del__() 函数中,我的程序也不会退出,它只会挂起,直到我发出键盘中断。我还尝试再次执行 TimerThread.cancel、sleep(0.1)、TimerThread.cancel,以防万一我碰巧取消了计时器,因为它在上下文检查功能中。结果相同。我还尝试将 TimerThread.cancel 放在 onDestroy 函数中(这又会调用 __del__ 析构函数)但没有变化。 GTK 循环退出,GUI 消失,但程序只是挂在控制台中,直到键盘中断。当我做一个键盘中断时,我从线程库中得到一个回溯错误。
还有其他方法可以终止线程吗?在退出之前我还需要采取其他步骤来杀死线程库吗?我是否误解了 Timer 线程的工作原理?
以下是代码的相关部分: https://paste.ubuntu.com/p/kQVfF78H5R/
编辑: 这是回溯,如果有帮助的话。
^CException ignored in: <module 'threading' from '/usr/lib/python3.7/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 1281, in _shutdown
t.join()
File "/usr/lib/python3.7/threading.py", line 1032, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
KeyboardInterrupt
【问题讨论】:
-
请将代码直接粘贴到帖子中。
-
@constt 过去有人告诉我,除了几行以外的任何内容都应该不直接粘贴到帖子中。是哪个?
-
根据rules,对你发的代码长度没有严格要求。如果您提供 live 示例,我认为在其他地方发布代码并链接到它是合理的。在其他情况下,最好将代码包含在问题中。
标签: python-3.x multithreading gtk