_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 атрибут аргумента хук - 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, например, для индексации словаря поток-specific данных. Идентификаторы потоков могут быть повторно использованы при выходе из поток и создании другого поток.

_thread.get_native_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 KiB в настоящее время является минимальным поддерживаемым размером стека значение, чтобы гарантировать достаточное пространство для самого интерпретатора. Следует отметить, что некоторые платформы могут иметь особые ограничения на значения размера стека, такие как требование минимального размера стека > 32 KiB или требование выделения кратного размера страницы системной памяти - для получения дополнительной информации следует обратиться к документации платформы (4 KiB страниц являются общими; использование кратных 4096 для размера стека является предложенным подходом при отсутствии более конкретной информации).

Availability: Windows, systems with POSIX threads.

_thread.TIMEOUT_MAX

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

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

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

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

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

Если присутствует аргумент integer 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 предложения соблюдаются), а стандартные файлы I/O не очищаются.