检查当前线程是否为主线程,Python中

56 投票
3 回答
40218 浏览
提问于 2025-04-18 03:39

之前已经有人回答过如何在 AndroidObjective CC++ 中检查当前线程是否是主线程,但似乎还没有人针对 Python 提出过类似的问题。我该如何可靠地判断当前线程是否是主线程呢?我想到了几种方法,但都不太让我满意,因为如果有 threading.MainThread 这个东西,那就简单多了。

检查线程名称

主线程是在 threading.py 中这样创建的:

Thread.__init__(self, name="MainThread")

所以可以这样做:

if threading.current_thread().name == 'MainThread'

但这个名称是固定的吗?我见过的其他代码是检查线程名称中是否包含 MainThread

存储启动线程

我可以在程序启动的瞬间存储一个对启动线程的引用,也就是在还没有其他线程的时候。这种方法绝对可靠,但对于这样一个简单的问题来说,似乎太麻烦了。

有没有更简洁的方法呢?

3 个回答

2

如果你和我一样,看到受保护的属性会感到不安,那么你可能想找一个替代方法来使用 threading._MainThread,正如所建议的。在这种情况下,你可以利用一个事实,那就是只有主线程可以处理信号,所以下面的代码可以解决这个问题:

import signal
def is_main_thread():
    try:
        # Backup the current signal handler
        back_up = signal.signal(signal.SIGINT, signal.SIG_DFL)
    except ValueError:
        # Only Main Thread can handle signals
        return False
    # Restore signal handler
    signal.signal(signal.SIGINT, back_up)
    return True

更新了内容,以解决 @user4815162342 提出的潜在问题。

28

这里的回答都比较旧或者不太好,所以我来提供一个最新的解决方案:

if threading.current_thread() is threading.main_thread():
    ...

这个方法从Python 3.4版本开始就可以用了。

81

使用 threading.current_thread().name == 'MainThread' 这个方法的问题在于,总是可以这样做:

threading.current_thread().name = 'MyName'
assert threading.current_thread().name == 'MainThread' # will fail

也许下面这个方法更可靠:

threading.current_thread().__class__.__name__ == '_MainThread'

不过,还是有可能有人会聪明地这样做:

threading.current_thread().__class__.__name__ = 'Grrrr'
assert threading.current_thread().__class__.__name__ == '_MainThread' # will fail

但是这个选择似乎更好;“毕竟,我们都是成年人了。”

更新:

Python 3.4 引入了 threading.main_thread(),这个方法比上面的要好得多:

assert threading.current_thread() is threading.main_thread()

更新 2:

对于 Python 版本低于 3.4,或许最好的选择是:

isinstance(threading.current_thread(), threading._MainThread)

撰写回答