Подтвердить что ты не робот

Проверьте, является ли текущий поток основным потоком, в Python

На это ответили Android, Цель C и С++ раньше, но, по-видимому, не для Python. Как я уверенно определить, является ли текущий поток основным потоком? Я могу придумать несколько подходов, ни одна из которых на самом деле не удовлетворяет меня, учитывая, что это может быть так же просто, как сравнение с threading.MainThread, если оно существует.

Проверьте имя потока

Основной поток создается в threading.py следующим образом:

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

чтобы можно было сделать

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

но это имя исправлено? Другие коды, которые я видел, проверяли, содержится ли MainThread в любом месте имени потока.

Сохраните начальный поток

Я мог бы хранить ссылку на начальную нить в момент запуска программы, т.е. пока нет других потоков. Это было бы абсолютно надежным, но слишком громоздким для такого простого запроса?

Есть ли более сжатый способ сделать это?

4b9b3361

Ответ 1

Проблема с 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

Но этот вариант все же кажется лучше; в конце концов, мы все соглашаем взрослых здесь.

UPDATE:

В Python 3.4 представлен threading.main_thread(), который намного красивее выше:

assert threading.current_thread() == threading.main_thread()

ОБНОВЛЕНИЕ 2:

Как уже упоминалось в комментарии ниже, пользователем1300959, другой жизнеспособный и чистый вариант:

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

Ответ 2

Ответы здесь старые и/или плохие, поэтому вот текущее решение:

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

Этот метод доступен с Python 3.4+.

Ответ 3

Если, как и я, доступ к защищенным атрибутам дает вам Heebie-jeebies, вам может понадобиться альтернатива для использования 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.