_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, оно молча игнорируется.

Изменено в версии 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.

Добавлено в версии 3.8.

_thread.stack_size([size])

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

Availability: Windows, системы с потоками POSIX.

_thread.TIMEOUT_MAX

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

Добавлено в версии 3.2.

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

lock.acquire(waitflag=1, timeout=- 1)

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

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

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

Возвращаемое значение 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), и стандартные файлы ввода-вывода не промываются.

Вернуться на верх