Сообщить об ошибке.

Получение общих сведений о потоках, модуль threading в Python

Функции, дающие сведения о запущенных потоках

В разделе рассмотрены функции модуля threading, при помощи которых можно узнать общие сведения о потоках, запущенных в программе.

Содержание:


threading.active_count():

Функция threading.active_count() возвращает количество живых потоков - объектов threading.Thread(). Возвращенное количество равно длине списка, возвращаемого функцией threading.enumerate().

import threading, time

def worker():
    time.sleep(1)

for _ in range(6):
    thread = threading.Thread(target=worker)
    thread.start()

# использование 'threading.active_count()'
# 7 потоков = 6 порожденных + 1 основной
n_thread =  threading.active_count()
print(n_thread)
# 7

threading.current_thread():

Функция threading.current_thread() возвращает текущий поток - объект threading.Thread(), соответствующий потоку управления вызывающего объекта.

Если поток управления вызывающего объекта не был создан через модуль потоковой передачи, то возвращается фиктивный объект потока с ограниченной функциональностью.

import threading, time, logging

def worker():
    # использование 'threading.current_thread()'
    # получаем экземпляр Thread и атрибутом
    # .name извлекаем имя потока
    thread_name = threading.current_thread().name
    logging.debug(f'Starting {thread_name}')
    time.sleep(1)

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(levelname)s] %(message)s',
)

th1 = threading.Thread(target=worker)
th1.start()
th2 = threading.Thread(name='worker', target=worker)
th2.start()

# [DEBUG] Starting Thread-1
# [DEBUG] Starting worker

threading.excepthook(args, /):

Функция threading.excepthook() обрабатывает неперехваченные исключения, вызванные в методе Thread.run().

Аргумент args имеет следующие атрибуты:

  • exc_type: Тип исключения.
  • exc_value: Значение исключения, может быть None.
  • exc_traceback: Трассировка исключения, может быть None.
  • thread: Поток, который вызвал исключение, может быть None.

Если аргумент exc_type это SystemExit, то исключение игнорируется. В противном случае исключение выводится в sys.stderr.

Если функция threading.excepthook() вызывает исключение, то для его обработки вызывается sys.excepthook().

Функцию threading.excepthook() можно переопределить, чтобы контролировать, как обрабатываются неперехваченные исключения, вызванные методом Thread.run().

Сохранение аргумента exc_value с использованием пользовательского хука может создать ссылочный цикл. Его следует явно очистить, когда исключение больше не требуется.

Сохранение потока с использованием пользовательского хука может воскресить его, если он установлен на финализируемый объект. Чтобы избежать воскрешения объектов, избегайте сохранения потока после завершения пользовательского хука.

Смотрите также функцию sys.excepthook(), которая обрабатывает неперехваченные исключения в однопоточных программах.

Новое в Python 3.8.

threading.get_ident():

Функция threading.get_ident() возвращает идентификатор текущего потока. Это ненулевое целое число.

Возвращаемое число не имеет прямого значения. Оно предназначено для использования в качестве "волшебного" файла cookie, например для индексации словаря данных, специфичных для потока.

Идентификаторы потока могут быть повторно использованы при выходе из потока и создании другого потока.

import threading, time, logging

def worker():
    name = threading.current_thread().name
    # использование 'threading.get_ident()'
    ident = threading.get_ident()
    # тоже самое можно получить через атрибут
    ident = threading.ident
    logging.debug(f'Starting {name}, id: {ident}')
    time.sleep(1)

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(levelname)s] %(message)s',
)

for _ in range(3):
    thread = threading.Thread(target=worker)
    thread.start()

# [DEBUG] Starting Thread-1, id: 140190611068672
# [DEBUG] Starting Thread-2, id: 140190602675968
# [DEBUG] Starting Thread-3, id: 140190594283264

threading.get_native_id():

Функция threading.get_native_id() возвращает собственный интегральный идентификатор текущего потока, назначенный ядром. Это неотрицательное целое число.

Его значение может использоваться для уникальной идентификации этого конкретного потока в масштабах всей системы до тех пор, пока поток не завершится, после чего это значение может быть переработано ОС.

Пример получения собственного интегрального идентификатора такой же как у threading.get_ident()

Доступность: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX.

Новое в Python 3.8.

threading.enumerate():

Функция threading.enumerate() возвращает список объектов threading.Thread() всех живых потоков.

В список входят демонические потоки и объекты фиктивного потока плюс основной поток. В этот список не входят завершенные потоки и потоки, которые еще не были запущены.

import threading, time, logging

def worker():
    time.sleep(1)

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(levelname)s] %(message)s',
)

for _ in range(3):
    thread = threading.Thread(target=worker)
    thread.start()

# использование 'threading.enumerate()'
# проходимся по экземплярам 'Thread'
# и из которых атрибутом '.name'
# извлекаем имена живых потоков
for t in threading.enumerate():
    logging.debug(f'Thread Name: {t.name}')

# [DEBUG] Thread Name: MainThread
# [DEBUG] Thread Name: Thread-1
# [DEBUG] Thread Name: Thread-2
# [DEBUG] Thread Name: Thread-3

threading.main_thread():

Функция threading.main_thread() возвращает объект основной потока.

В нормальных условиях основным потоком является поток, из которого был запущен интерпретатор Python.

import threading, time, logging

def worker():
    name = threading.current_thread().name
    time.sleep(1)
    logging.debug(f'Ending {name}')

logging.basicConfig(
    level=logging.DEBUG,
    format='[%(levelname)s] %(message)s',
)

# использование 'threading.main_thread()'
# получаем экземпляр основного потока
main_thread = threading.main_thread()
# получаем имя основного потока
main_thread_name = main_thread.name
logging.debug(f'{main_thread_name} starting...')

for _ in range(3):
    thread = threading.Thread(target=worker)
    thread.start()


for t in threading.enumerate():
    # Список 'threading.enumerate()' включает в себя основной 
    # поток и т.к. присоединение основного потока самого к себе 
    # приводит к тупиковой ситуации, то его необходимо пропустить
    if t is main_thread:
        continue
    thead_name = t.name
    logging.debug(f'{main_thread_name} joining {thead_name}')
    t.join()
    
# [DEBUG] MainThread starting...
# [DEBUG] MainThread joining Thread-1
# [DEBUG] Ending Thread-1
# [DEBUG] MainThread joining Thread-2
# [DEBUG] Ending Thread-3
# [DEBUG] Ending Thread-2
# [DEBUG] MainThread joining Thread-3

threading.TIMEOUT_MAX:

Константа threading.TIMEOUT_MAX представляет собой максимально допустимое значение для параметра тайм-аута функция блокировки (Lock.acquire(), RLock.acquire(), Condition.wait(), и т. д.).

Указание времени ожидания, превышающее это значение будет вызывать исключение OverflowError.

>>> import threading
>>> threading.TIMEOUT_MAX
# 9223372036.0