检查当前线程是否为主线程,Python中
之前已经有人回答过如何在 Android、Objective C 和 C++ 中检查当前线程是否是主线程,但似乎还没有人针对 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)