_thread – Низкоуровневый API для работы с потоками¶_thread – Low-level threading 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 аргумента hook равен function. По умолчанию печатается трассировка стека, после чего поток завершается (но другие потоки продолжают работу).Когда функция вызывает исключение
SystemExit, оно игнорируется без уведомления.Изменено в версии 3.8: Теперь для обработки необработанных исключений используется
sys.unraisablehook().
-
_thread.interrupt_main()¶ Имитирует эффект поступления сигнала
signal.SIGINTв главный поток. Поток может использовать эту функцию для прерывания главного потока.Если
signal.SIGINTне обрабатывается Python (установлено значениеsignal.SIG_DFLилиsignal.SIG_IGN), эта функция ничего не делает.
-
_thread.exit()¶ Вызывает исключение
SystemExit. Если оно не перехвачено, поток завершится без уведомления.
-
_thread.allocate_lock()¶ Возвращает новый объект блокировки. Методы блокировок описаны ниже. Изначально блокировка не установлена.
-
_thread.get_ident()¶ Возвращает «идентификатор потока» текущего потока. Это ненулевое целое число. Его значение не имеет прямого смысла; оно предназначено в качестве «магического ключа» для использования, например, в качестве индекса в словаре данных, специфичных для потока. Идентификаторы потоков могут быть повторно использованы после завершения потока и создания другого.
-
_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возникнет после того, как блокировка будет захвачена.При завершении главного потока решение о том, будут ли существовать другие потоки, зависит от системы. В большинстве систем они уничтожаются без выполнения предложений
try…finallyили вызова деструкторов объектов.При завершении главного потока он не выполняет никакой обычной очистки (за исключением того, что предложения
try…finallyсоблюдаются), и стандартные файлы ввода-вывода не сбрасываются.