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

16.3. thread – Множество потоков управленияthread – Multiple threads of control

Примечание

Модуль thread был переименован в _thread в Python 3. Инструмент 2to3 будет автоматически адаптировать импорты при преобразовании исходных кодов в Python 3; однако следует рассмотреть использование высокоуровневого модуля threading вместо этого.

Этот модуль предоставляет низкоуровневые примитивы для работы с несколькими потоками (также называемыми легковесными процессами или задачами) – множеством потоков управления, разделяющих общее пространство данных. Для синхронизации предоставляются простые блокировки (также называемые мьютексами или двоичными семафорами). Модуль 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 в главном потоке. Подпоток может использовать эту функцию, чтобы прервать главный поток.

Новое в версии 2.3.

thread.exit()

Вызывает исключение SystemExit. Если оно не перехвачено, поток завершится без уведомления.

thread.allocate_lock()

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

thread.get_ident()

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

thread.stack_size([size])

Возвращает размер стека потока, используемый при создании новых потоков. Необязательный аргумент size задаёт размер стека для последующих создаваемых потоков и должен быть 0 (использовать платформенное или настроенное значение по умолчанию) или положительным целым числом не менее 32 768 (32 КБ). Если size не указан, используется 0. Если изменение размера стека потока не поддерживается, возбуждается исключение error. Если указанный размер стека недействителен, возбуждается ValueError, а размер стека остаётся неизменным. 32 КБ – текущее минимальное поддерживаемое значение размера стека для гарантии достаточного пространства стека для самого интерпретатора. Обратите внимание, что некоторые платформы могут иметь особые ограничения на значения размера стека, например, требовать минимальный размер стека > 32 КБ или требовать выделение памяти, кратное размеру страницы системной памяти; для получения дополнительной информации следует обратиться к документации платформы (обычно используются страницы 4 КБ; при отсутствии более конкретной информации рекомендуется использовать значения, кратные 4096, для размера стека). Доступность: Windows, системы с потоками POSIX.

Новое в версии 2.5.

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

lock.acquire([waitflag])

Без необязательного аргумента этот метод захватывает блокировку безусловно, при необходимости ожидая, пока она не будет освобождена другим потоком (только один поток за раз может захватить блокировку – в этом их смысл). Если присутствует целочисленный аргумент waitflag, действие зависит от его значения: если он равен нулю, блокировка захватывается только в том случае, если её можно захватить немедленно без ожидания, а если он не равен нулю, блокировка захватывается безусловно, как и раньше. Возвращаемое значение – True, если блокировка захвачена успешно, False в противном случае.

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 возникнет после того, как блокировка будет захвачена.

  • Когда главный поток завершается, переживут ли остальные потоки, определяется системой. На SGI IRIX с использованием собственной реализации потоков они переживают. На большинстве других систем они уничтожаются без выполнения предложений tryfinally или выполнения деструкторов объектов.

  • При завершении главного потока он не выполняет никакой обычной очистки (за исключением того, что предложения tryfinally соблюдаются), и стандартные файлы ввода-вывода не сбрасываются.