Как работает метод `threading.Thread()`?

Метод threading.Thread() в Python создает новый поток выполнения. Он не запускает поток сразу. В конструктор передаются аргументы:
  • target: функция, которую будет выполнять поток.
  • args: кортеж аргументов для этой функции.
  • kwargs: словарь именованных аргументов для этой функции.
  • daemon: определяет, является ли поток "демоном".
Чтобы поток начал выполняться, необходимо вызвать метод start() у созданного объекта Thread. При вызове start() вызывается метод run(), который, в свою очередь, вызывает функцию, указанную в target.

Метод threading.Thread() используется для создания и управления потоками в Python. Он представляет собой конструктор класса threading.Thread, который позволяет создать новый поток выполнения, параллельный основному потоку программы.

Основные этапы работы threading.Thread():

  1. Создание экземпляра: При вызове threading.Thread() создается экземпляр класса Thread. Этот экземпляр представляет собой новый поток, который еще не запущен.
  2. Инициализация: Конструктор Thread() принимает несколько аргументов, которые позволяют настроить поведение потока. Наиболее важные аргументы:

    • target: Функция, которая будет выполняться в новом потоке. Это обязательный аргумент.
    • args: Кортеж аргументов, которые будут переданы в функцию target.
    • kwargs: Словарь именованных аргументов, которые будут переданы в функцию target.
    • name: Необязательное имя для потока (строка). Полезно для отладки. Если не указано, потоку будет присвоено имя вида "Thread-N", где N - число.
    • daemon: Булево значение, указывающее, является ли поток демоном. Если True, поток будет завершен при завершении основного потока. По умолчанию False.
  3. Запуск потока: Чтобы начать выполнение функции target в новом потоке, необходимо вызвать метод start() экземпляра Thread. start() выполняет следующие действия:
    • Подготавливает новый поток к выполнению.
    • Вызывает метод run() в новом потоке.
    • Метод run() по умолчанию вызывает функцию, переданную в аргументе target, передавая ей аргументы args и kwargs.
  4. Параллельное выполнение: После вызова start() новый поток начинает выполняться параллельно основному потоку. Это означает, что оба потока могут выполнять код одновременно (или псевдо-параллельно, в зависимости от GIL - Global Interpreter Lock - в реализации CPython).
  5. Завершение потока: Поток завершается, когда функция target завершает свое выполнение. Также, потоки-демоны могут завершаться автоматически при завершении основного потока.
  6. Ожидание завершения потока (join): Метод join() экземпляра Thread позволяет основному потоку ожидать завершения указанного потока. Это может быть полезно, когда необходимо дождаться результатов работы потока, прежде чем продолжить выполнение основного потока. join() блокирует выполнение текущего потока до тех пор, пока не завершится поток, для которого он был вызван.

Пример:


    import threading
    import time

    def my_function(name):
        print(f"Поток {name}: запущен")
        time.sleep(2)  # Имитация работы
        print(f"Поток {name}: завершен")

    # Создание потока
    my_thread = threading.Thread(target=my_function, args=("Поток 1",))

    # Запуск потока
    my_thread.start()

    print("Основной поток: ожидает завершения потока...")
    my_thread.join() # Ожидание завершения потока

    print("Основной поток: завершен")
  

В этом примере создается поток, который выполняет функцию my_function. Основной поток ждет завершения созданного потока, прежде чем завершиться самому. Важно понимать, что GIL в CPython может ограничивать реальную параллельность для CPU-bound задач, но threading полезен для I/O-bound задач.

0