Python - Создание потока

Привет, начинающие программисты на Python! Сегодня мы погружаемся в захватывающий мир потоков. Не волнуйтесь, если вы раньше не слышали о потоках – мы начнем с самого начала и постепенно развиваться. К концу этого урока вы будете создавать потоки как про!

Python - Creating a Thread

Что такое потоки?

Прежде чем перейти к созданию потоков, давайте поймем, что это такое. Представьте себе, что вы готовите сложное блюдо. Вы не делаете все одно за другим – возможно, у вас картофель варит на одном конфорке, а вы режете овощи на разделочной доске. Это похоже на то, как работают потоки в программировании. Они позволяют различным частям вашей программы работать параллельно, делая ваш код более эффективным.

Создание потоков с помощью функций

Самый простой способ создать поток в Python – это использовать функцию. Давайте начнем с простого примера:

import threading
import time

def print_numbers():
for i in range(5):
print(f"Number {i}")
time.sleep(1)

# Создание потока
thread = threading.Thread(target=print_numbers)

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

print("Основной поток продолжает работу")

# Ожидание завершения потока
thread.join()

print("Поток завершен")

Разберем это:

  1. Мы импортируем модуль threading, который предоставляет нам инструменты для работы с потоками.
  2. Мы определяем простую функцию print_numbers(), которая выводит числа от 0 до 4 с задержкой в 1 секунду между каждым выводом.
  3. Мы создаем поток, используя threading.Thread(), указывая нашу функцию в качестве target.
  4. Мы запускаем поток с помощью thread.start().
  5. Основная программа продолжает работу, выводя "Основной поток продолжает работу".
  6. Мы используем thread.join(), чтобы дождаться завершения нашего потока перед продолжением.

Когда вы запустите это, вы увидите, что "Основной поток продолжает работу" выводится мгновенно, в то время как числа выводятся в фоновом режиме. Вот сила потоков!

Создание потоков путем расширения класса Thread

Другой способ создания потоков – это расширение класса Thread. Этот метод полезен, когда вы хотите создать повторно используемый объект потока. Вот пример:

import threading
import time

class NumberPrinter(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name

def run(self):
for i in range(5):
print(f"{self.name}: Number {i}")
time.sleep(1)

# Создание двух потоков
thread1 = NumberPrinter("Поток 1")
thread2 = NumberPrinter("Поток 2")

# Запуск потоков
thread1.start()
thread2.start()

print("Основной поток продолжает работу")

# Ожидание завершения обоих потоков
thread1.join()
thread2.join()

print("Оба потока завершены")

В этом примере:

  1. Мы определяем класс NumberPrinter, который расширяет threading.Thread.
  2. Мы переопределяем метод __init__, чтобы принимать имя для нашего потока.
  3. Мы переопределяем метод run, который вызывается при запуске потока.
  4. Мы создаем два экземпляра нашего класса NumberPrinter и запускаем их.
  5. Оба потока работают параллельно, выводя свои числа.

Этот метод дает нам больше контроля над потоками и позволяет легко создавать несколько экземпляров.

Создание потоков с помощью функции start_new_thread()

Есть третий способ создания потоков в Python, используя функцию start_new_thread() из модуля _thread. Однако этот метод считается низкоуровневым и не рекомендуется для большинства случаев использования. Вот пример для полноты:

import _thread
import time

def print_numbers(thread_name):
for i in range(5):
print(f"{thread_name}: Number {i}")
time.sleep(1)

# Запуск двух новых потоков
try:
_thread.start_new_thread(print_numbers, ("Поток 1",))
_thread.start_new_thread(print_numbers, ("Поток 2",))
except:
print("Ошибка: не удалось запустить поток")

# Поддержание работы основного потока
time.sleep(6)
print("Основной поток завершает работу")

Этот метод менее гибкий и не предоставляет такого же контроля, как предыдущие методы. Также сложнее дождаться завершения потоков с использованием этого подхода.

Сравнение методов создания потоков

Вот краткое сравнение трех методов, о которых мы обсуждали:

Метод Плюсы Минусы
Использование функций Простота реализации, хорошо для одноразовых задач Меньше повторного использования, ограниченный контроль
Расширение класса Thread Повторное использование, больше контроля, объектно-ориентированный Немного сложнее настройка
start_new_thread() Низкоуровневый контроль Труднее управлять, менее гибкий, не рекомендуется

Заключение

Поздравляем! Вы только что сделали первые шаги в мир потоков в Python. Мы рассмотрели три разных способа создания потоков, каждый из которых имеет свои преимущества и случаи использования. Помните, потоки могут сделать ваши программы более эффективными, но также вносят сложность. Когда вы продолжите свое погружение в Python, вы узнаете больше о том, когда и как эффективно использовать потоки.

Продолжайте практиковаться, и скоро вы будете работать с потоками как опытный программист. Счастливого кодирования!

Credits: Image by storyset