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


Этот модуль предоставляет низкоуровневые примитивы для работы с несколькими потоками (также называемыми легковесные процессы или задачи) — несколькими потоками управления, совместно использующими своё глобальное пространство данных. Для синхронизации предусмотрены простые блокировки (также называемые мьютексы или двоичные семафоры). Модуль 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 аргумента ловушки — function. По умолчанию печатается трассировка стека, а затем поток завершается (но другие потоки продолжают выполняться).

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

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

_thread.interrupt_main()

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

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

_thread.exit()

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

_thread.exit_prog(status)

Закрыть все потоки и сообщить значение целочисленного аргумента status как статус завершения всей программы. Предупреждение: код в ожидающих предложениях finally, в этом потоке или в других потоках, не выполняется.

_thread.allocate_lock()

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

_thread.get_ident()

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

_thread.get_native_id()

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

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

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

_thread.stack_size([size])

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

Доступность: 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), а стандартные файлы ввода-вывода не сбрасываются.