_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, вона мовчки ігнорується.

Raises an auditing event _thread.start_new_thread with arguments function, args, kwargs.

Змінено в версії 3.8: sys.unraisablehook() тепер використовується для обробки необроблених винятків.

_thread.interrupt_main(signum=signal.SIGINT, /)

Імітуйте ефект сигналу, що надходить у головний потік. Потік може використовувати цю функцію для переривання основного потоку, хоча немає гарантії, що переривання відбудеться негайно.

If given, signum is the number of the signal to simulate. If signum is not given, signal.SIGINT is simulated.

If the given signal isn’t handled by Python (it was set to signal.SIG_DFL or signal.SIG_IGN), this function does nothing.

Змінено в версії 3.10: Аргумент signum додається для налаштування номера сигналу.

Примітка

Це не випромінює відповідний сигнал, але планує виклик пов’язаного обробника (якщо він існує). Якщо ви хочете справді випромінювати сигнал, використовуйте signal.raise_signal().

_thread.exit()

Підніміть виняток SystemExit. Якщо не буде спіймано, це призведе до тихого виходу потоку.

_thread.allocate_lock()

Повернути новий об’єкт блокування. Способи блокування описані нижче. Замок спочатку розблокований.

_thread.get_ident()

Повертає «ідентифікатор потоку» поточного потоку. Це ненульове ціле число. Його значення не має прямого значення; воно призначене як магічне печиво, яке можна використовувати, наприклад. щоб індексувати словник даних, що стосуються потоку. Ідентифікатори потоку можуть бути перероблені, коли потік завершується та створюється інший.

_thread.get_native_id()

Повертає власний інтегральний ідентифікатор потоку поточного потоку, призначеного ядром. Це невід’ємне ціле число. Його значення може використовуватися для однозначної ідентифікації цього конкретного потоку в системі (до завершення роботи потоку, після чого значення може бути повторно використано ОС).

Availability: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD.

Added in version 3.8.

_thread.stack_size([size])

Повертає розмір стека потоків, який використовувався під час створення нових потоків. Необов’язковий аргумент size визначає розмір стека, який буде використовуватися для згодом створених потоків, і має дорівнювати 0 (використовувати платформу або налаштоване за замовчуванням) або додатне ціле значення принаймні 32 768 (32 КіБ). Якщо size не вказано, використовується 0. Якщо зміна розміру стека потоку не підтримується, виникає RuntimeError. Якщо вказаний розмір стека недійсний, виникає помилка ValueError і розмір стека не змінюється. 32 КіБ наразі є мінімальним підтримуваним значенням розміру стеку, щоб гарантувати достатній простір стеку для самого інтерпретатора. Зауважте, що деякі платформи можуть мати певні обмеження щодо значень розміру стека, як-от вимагати мінімальний розмір стека > 32 КБ або вимагати виділення кратного розміру сторінки системної пам’яті – для отримання додаткової інформації слід звернутися до документації платформи (сторінки 4 КБ є поширеними; використання кратних 4096 для розміру стека є запропонованим підходом за відсутності більш конкретної інформації).

Availability: Windows, pthreads.

Unix platforms with POSIX threads support.

_thread.TIMEOUT_MAX

The maximum value allowed for the timeout parameter of Lock.acquire. Specifying a timeout greater than this value will raise an OverflowError.

Added in version 3.2.

Об’єкти блокування мають такі методи:

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

Без будь-яких необов’язкових аргументів цей метод отримує блокування безумовно, за необхідності чекаючи, поки його не буде звільнено іншим потоком (лише один потік за раз може отримати блокування — це причина їхнього існування).

If the blocking argument is present, the action depends on its value: if it is False, the lock is only acquired if it can be acquired immediately without waiting, while if it is True, the lock is acquired unconditionally as above.

If the floating-point timeout argument is present and positive, it specifies the maximum wait time in seconds before returning. A negative timeout argument specifies an unbounded wait. You cannot specify a timeout if blocking is 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().

  • It is not possible to interrupt the acquire() method on a lock — the KeyboardInterrupt exception will happen after the lock has been acquired.

  • Коли основний потік виходить, система визначає, чи виживуть інші потоки. У більшості систем вони припиняються без виконання пропозицій tryfinally або виконання деструкторів об’єктів.

  • Коли основний потік завершується, він не виконує жодного звичайного очищення (окрім того, що враховуються пропозиції tryfinally), а стандартні файли вводу/виводу не очищуються.