_thread — Низкоуровневый потоковый API


Этот модуль предоставляет низкоуровневые примитивы для работы с несколькими потоками (также называемыми light-weight processes или tasks) — несколькими потоками управления, разделяющими глобальное пространство данных. Для синхронизации предусмотрены простые блокировки (также называемые mutexes или binary semaphores). Модуль threading предоставляет более простой в использовании и высокоуровневый API для работы с потоками, построенный поверх этого модуля.

Изменено в версии 3.7: Раньше этот модуль был необязательным, теперь он доступен всегда.

В этом модуле определены следующие константы и функции:

exception _thread.error

Возникает при ошибках, специфичных для потока.

Изменено в версии 3.3: Теперь это синоним встроенного RuntimeError.

_thread.LockType

Это тип объектов блокировки.

_thread.start_new_thread(function, args[, kwargs])

Запускает новый поток и возвращает его идентификатор. Поток выполняет функцию function со списком аргументов args (который должен быть кортежем). Необязательный аргумент kwargs задает словарь аргументов-ключей.

Когда функция возвращается, поток тихо завершается.

Если функция завершается с необработанным исключением, вызывается sys.unraisablehook() для обработки исключения. Атрибутом object аргумента hook является function. По умолчанию выводится трассировка стека, после чего поток завершается (но другие потоки продолжают работать).

Если функция вызывает исключение SystemExit, оно молча игнорируется.

Поднимает auditing event _thread.start_new_thread с аргументами function, args, kwargs.

Изменено в версии 3.8: sys.unraisablehook() теперь используется для обработки необработанных исключений.

_thread.interrupt_main(signum=signal.SIGINT, /)

Имитирует эффект поступления сигнала в главный поток. Поток может использовать эту функцию для прерывания главного потока, хотя нет никакой гарантии, что прерывание произойдет немедленно.

Если задано, signum - это номер сигнала, который нужно смоделировать. Если signum не задан, моделируется signal.SIGINT.

Если заданный сигнал не обрабатывается Python (он был установлен в signal.SIG_DFL или signal.SIG_IGN), эта функция ничего не делает.

Изменено в версии 3.10: Аргумент signum добавляется для настройки номера сигнала.

Примечание

Это не вызывает соответствующий сигнал, но планирует вызов связанного с ним обработчика (если он существует). Если вы хотите действительно издать сигнал, используйте signal.raise_signal().

_thread.exit()

Вызывает исключение SystemExit. Если его не поймать, то поток завершится без звука.

_thread.allocate_lock()

Возвращает новый объект блокировки. Методы блокировок описаны ниже. Изначально замок разблокирован.

_thread.get_ident()

Возвращает «идентификатор потока» текущего потока. Это ненулевое целое число. Его значение не имеет прямого смысла; оно предназначено в качестве магического cookie, которое можно использовать, например, для индексации словаря данных, специфичных для потока. Идентификаторы потоков могут быть повторно использованы при выходе из потока и создании другого потока.

_thread.get_native_id()

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

Availability: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD, GNU/kFreeBSD.

Added in version 3.8.

Изменено в версии 3.13: Добавлена поддержка GNU/kFreeBSD.

_thread.stack_size([size])

Возвращает размер стека потоков, используемый при создании новых потоков. Необязательный аргумент size задает размер стека, который будет использоваться для последующих созданных потоков, и должен быть равен 0 (использование платформы или конфигурации по умолчанию) или целому положительному значению не менее 32 768 (32 килобайта). Если size не указан, используется 0. Если изменение размера стека потоков не поддерживается, возникает ошибка RuntimeError. Если указанный размер стека недопустим, выдается сообщение ValueError, и размер стека не изменяется. В настоящее время минимальный поддерживаемый размер стека составляет 32 килобайта, чтобы гарантировать достаточное пространство стека для самого интерпретатора. Обратите внимание, что некоторые платформы могут иметь особые ограничения на значения размера стека, например, требовать минимальный размер стека > 32 килобайт или требовать выделения кратного размера страницы системной памяти - для получения дополнительной информации следует обратиться к документации платформы (страницы размером 4 килобайта являются обычными; при отсутствии более конкретной информации рекомендуется использовать для размера стека кратное 4096).

Availability: Windows, pthreads.

Платформы Unix с поддержкой потоков POSIX.

_thread.TIMEOUT_MAX

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

Added in version 3.2.

У объектов блокировки есть следующие методы:

lock.acquire(blocking=True, timeout=-1)

Без дополнительного аргумента этот метод приобретает блокировку безоговорочно, при необходимости дожидаясь, пока она не будет освобождена другим потоком (только один поток одновременно может приобретать блокировку - такова причина их существования).

Если присутствует аргумент blocking, действие зависит от его значения: если оно равно false, блокировка будет получена только в том случае, если она может быть получена немедленно без ожидания, если же оно равно true, блокировка будет получена безусловно, как указано выше.

Если аргумент timeout с плавающей точкой присутствует и является положительным, он задает максимальное время ожидания в секундах перед возвратом. Отрицательный аргумент timeout указывает на неограниченное время ожидания. Вы не можете указать timeout, если blocking является ложным.

Возвращаемое значение True, если блокировка получена успешно, False, если нет.

Изменено в версии 3.2: Параметр timeout является новым.

Изменено в версии 3.2: Теперь получение блокировки может быть прервано сигналами на POSIX.

lock.release()

Освобождает блокировку. Блокировка должна быть получена ранее, но не обязательно тем же потоком.

lock.locked()

Возвращает статус блокировки: True, если она была получена каким-либо потоком, False, если нет.

Помимо этих методов, объекты блокировки можно также использовать с помощью оператора with, например:

import _thread

a_lock = _thread.allocate_lock()

with a_lock:
    print("a_lock is locked while this executes")

** Пещеры:**

  • Потоки странно взаимодействуют с прерываниями: исключение KeyboardInterrupt будет получено произвольным потоком. (Когда доступен модуль signal, прерывания всегда поступают в главный поток).

  • Вызов sys.exit() или поднятие исключения SystemExit эквивалентны вызову _thread.exit().

  • Невозможно прервать метод acquire() на блокировке - исключение KeyboardInterrupt произойдет после того, как блокировка будет получена.

  • Когда главный поток завершается, система определяет, выживут ли другие потоки. В большинстве систем они уничтожаются без выполнения tryfinally или выполнения деструкторов объектов.

  • Когда главный поток завершает свою работу, он не производит никакой обычной очистки (за исключением того, что выполняются условия tryfinally), и стандартные файлы ввода-вывода не промываются.