Документация Python неофициальный перевод

17.9. _thread – Низкоуровневый API для работы с потоками_thread – Low-level threading API

Этот модуль предоставляет низкоуровневые примитивы для работы с несколькими потоками (также называемыми легковесными процессами или задачами) – несколькими потоками управления, разделяющими общее пространство данных. Для синхронизации предоставляются простые блокировки (также называемые мьютексами или двоичными семафорами). Модуль threading предоставляет более простой и высокоуровневый API для работы с потоками, построенный на основе этого модуля.

Модуль является необязательным. Он поддерживается на Windows, Linux, SGI IRIX, Solaris 2.x, а также на системах, в которых есть реализация потоков POSIX (также известных как «pthread»). Для систем, в которых отсутствует модуль _thread, доступен модуль _dummy_thread. Он дублирует интерфейс этого модуля и может использоваться как его замена без дополнительных изменений.

Он определяет следующие константы и функции:

exception _thread.error

Возникает при ошибках, связанных с потоками.

Изменено в версии 3.3: Теперь это синоним встроенного исключения RuntimeError.

_thread.LockType

Это тип объектов блокировки.

_thread.start_new_thread(function, args[, kwargs])

Запускает новый поток и возвращает его идентификатор. Поток выполняет функцию function со списком аргументов args (который должен быть кортежем). Необязательный аргумент kwargs задаёт словарь именованных аргументов. Когда функция возвращает управление, поток беззвучно завершается. Когда функция завершается из-за необработанного исключения, печатается трассировка стека, и поток завершается (но остальные потоки продолжают работу).

_thread.interrupt_main()

Генерирует исключение KeyboardInterrupt в главном потоке. Дочерний поток может использовать эту функцию, чтобы прервать главный поток.

_thread.exit()

Генерирует исключение SystemExit. Если его не перехватить, это приведет к завершению потока без вывода сообщений.

_thread.allocate_lock()

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

_thread.get_ident()

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

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