Python - Создание потока
Привет, начинающие программисты на Python! Сегодня мы погружаемся в захватывающий мир потоков. Не волнуйтесь, если вы раньше не слышали о потоках – мы начнем с самого начала и постепенно развиваться. К концу этого урока вы будете создавать потоки как про!
Что такое потоки?
Прежде чем перейти к созданию потоков, давайте поймем, что это такое. Представьте себе, что вы готовите сложное блюдо. Вы не делаете все одно за другим – возможно, у вас картофель варит на одном конфорке, а вы режете овощи на разделочной доске. Это похоже на то, как работают потоки в программировании. Они позволяют различным частям вашей программы работать параллельно, делая ваш код более эффективным.
Создание потоков с помощью функций
Самый простой способ создать поток в 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("Поток завершен")
Разберем это:
- Мы импортируем модуль
threading
, который предоставляет нам инструменты для работы с потоками. - Мы определяем простую функцию
print_numbers()
, которая выводит числа от 0 до 4 с задержкой в 1 секунду между каждым выводом. - Мы создаем поток, используя
threading.Thread()
, указывая нашу функцию в качествеtarget
. - Мы запускаем поток с помощью
thread.start()
. - Основная программа продолжает работу, выводя "Основной поток продолжает работу".
- Мы используем
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("Оба потока завершены")
В этом примере:
- Мы определяем класс
NumberPrinter
, который расширяетthreading.Thread
. - Мы переопределяем метод
__init__
, чтобы принимать имя для нашего потока. - Мы переопределяем метод
run
, который вызывается при запуске потока. - Мы создаем два экземпляра нашего класса
NumberPrinter
и запускаем их. - Оба потока работают параллельно, выводя свои числа.
Этот метод дает нам больше контроля над потоками и позволяет легко создавать несколько экземпляров.
Создание потоков с помощью функции 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