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

16.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

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

_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 кБ). Если изменение размера стека потока не поддерживается, возбуждается ThreadError. Если указанный размер стека некорректен, возбуждается 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().
  • Не все встроенные функции, которые могут блокироваться в ожидании ввода-вывода, позволяют выполняться другим потокам. (Самые популярные из них (time.sleep(), file.read(), select.select()) работают как и ожидается.)
  • Невозможно прервать метод acquire() блокировки – исключение KeyboardInterrupt возникнет после того, как блокировка будет захвачена.
  • Когда главный поток завершается, вопрос о том, выживают ли другие потоки, определяется системой. На большинстве систем они уничтожаются без выполнения предложений try ... finally или деструкторов объектов.
  • Когда главный поток завершается, он не выполняет обычные действия по очистке (за исключением того, что предложения try ... finally выполняются), и стандартные файлы ввода-вывода не сбрасываются.