_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()

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

Availability: 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 размер - это предлагаемый подход в отсутствие более конкретной информации).

Availability: Окна, pthreads.

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

_thread.TIMEOUT_MAX

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

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

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

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

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

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

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

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

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