Многопоточность в Python

Многопоточность в Python
Иногда выполнение программы кажется слишком медленным, особенно когда приходится долго ожидать завершения одной задачи — например, загрузки данных из интернета или записи больших файлов. Чтобы сократить общее время работы и повысить эффективность, разработчики используют многопоточность. Этот подход позволяет выполнять несколько задач одновременно.

Разберем, что такое потоки, зачем существует многопоточность в python, как ее реализовать и какие инструменты существуют.

Что такое многопоточность в Python?

Многопоточность в Python — способ сделать так, чтобы программа могла выполнять сразу несколько задач одновременно. Например, пока одна задача считает числа, другая может подгружать данные из базы. Для этого создаются потоки (threads) — как дополнительные инструменты, которые работают внутри программы.

Пример применения многопоточности:

  • Онлайн-магазин одновременно обрабатывает заказы, обновляет информацию о наличии товаров на складе и отправляет уведомления пользователям.
  • Программа для мониторинга серверов собирает данные о нагрузке и доступности из разных регионов, обновляя дашборд в реальном времени.
Схема общей структуры многопоточности в Python
Один процесс разделяется на потоки для задач

Почему курсы

Сегодня курсы — это возможность быстро освоить востребованные профессии, особенно в digital-сфере. Вот несколько специальностей, которые можно изучить с нуля, и начать карьеру уже через несколько месяцев.
import threading
def count_down(start):
    """
    Отсчитывает числа от заданного значения до 1.
    """
    for i in range(start, 0, -1):
        print(f"Countdown: {i}")
# Создаем два потока с разным начальным значением отсчета
thread1 = threading.Thread(target=count_down, args=(5,))
thread2 = threading.Thread(target=count_down, args=(3,))
# Запускаем потоки
thread1.start()
thread2.start()
# Ожидаем завершения 
thread1.join()
thread2.join()
print("Отсчет завершен.")
Здесь функция count_down выполняет простой обратный отсчет чисел от заданного значения до 1. Первый считает от 5 до 1, второй считает от 3 до 1.

Как сделать многопоточность в Python?

Для создания и управления потоками в Python используется специальный модуль threading. Вместо того чтобы делать задачи по очереди, программа справляется с ними параллельно, экономя время.
Работа потоков в Python
Параллельное выполнение задач в потоках ​​
Чтобы создать поток, выполните следующие шаги:

  1. Определите функцию, которая будет выполнять задачу.
  2. Передайте эту функцию в класс Thread через параметр target.
  3. Если функция принимает аргументы, передайте их с помощью параметра args в виде кортежа.
  4. Запустите поток с помощью метода start().
  5. Дождитесь завершения с помощью метода join().

Пример:
import threading
def count_words(filename):
    """
    Считает количество слов в файле и выводит результат.
    """
    try:
        with open(filename, "r") as file:
            text = file.read()
        word_count = len(text.split())
        print(f"{filename}: {word_count} слов")
    except FileNotFoundError:
        print(f"{filename}: файл не найден")
# Создаем два потока для работы с разными файлами
thread1 = threading.Thread(target=count_words, args=("file1.txt",))
thread2 = threading.Thread(target=count_words, args=("file2.txt",))
# Запускаем потоки
thread1.start()
thread2.start()
# Ожидаем завершения 
thread1.join()
thread2.join()
print("Обработка файлов завершена.")

Синхронизация потоков

Когда несколько threads выполняются одновременно и обращаются к одной и той же части программы или общим данным, могут возникнуть ошибки. Представьте, что два человека пытаются одновременно писать на одной доске: их записи могут пересекаться, и результат будет неразборчивым. В программировании эта проблема называется «состояние гонки» (race condition).

Чтобы предотвратить такие ситуации, используется синхронизация потоков — метод, который управляет доступом потоков к общим ресурсам, чтобы они не мешали друг другу. В Python для этого используется специальный инструмент — Lock (замок), который предоставляет модуль threading.

Как это работает?

  • Представим, что общий ресурс — это комната, а потоки — люди, которые хотят войти.
  • Замок (Lock) закрывает дверь, чтобы только один человек мог войти в комнату за раз.
  • Другие потоки (люди) ждут за дверью, пока текущий поток не выйдет (замок откроется).

Что такое ThreadPoolExecutor и чем он поможет?

Это инструмент, который позволяет выполнять несколько задач одновременно с использованием пула threads. Вы создаете группу потоков (например, 3 или 5), и задачи распределяются между ними автоматически.
Схема работы ThreadPoolExecutor с пулом потоков и задачами
Потоки распределяют задачи через ThreadPoolExecutor
Например, у вас есть программа, которая скачивает 50 файлов из интернета. Если вы начнете скачивать их один за другим, это займет много времени. Но если вы скачаете сразу несколько файлов параллельно, то будет быстрее. Именно для таких задач и нужен ThreadPoolExecutor.

Пример использования:
from concurrent.futures import ThreadPoolExecutor
def process_file(file_name):
    print(f"Processing file: {file_name}")
# Создаем пул из 3 threads
with ThreadPoolExecutor(max_workers=3) as executor:
    files = ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]
    executor.map(process_file, files)
Все файлы обрабатываются параллельно, ускоряя выполнение программы.
Подписка РБК Pro на 6 месяцев
Интенсив РБК Pro на выбор
Профессия Python-разработчик со скидкой до 57% и подарками на 135 000 ₽
3 мини-курса в подарок

Что есть помимо потоков в Python?

Для решения задач параллельного выполнения Python предлагает не только потоки. Существуют и другие подходы, которые эффективно справляются с ограничениями многопоточности, помогая обрабатывать данные быстрее и проще.
Альтернативы многопоточности в Python
Сравнение Threading, Multiprocessing и Asyncio ​
  • Если в питон многопоточность ограничена GIL (глобальной блокировкой интерпретатора), используйте модуль multiprocessing, который создает независимые процессы и задействует все ядра процессора — это идеально для ресурсоемких вычислений.
  • Для задач с задержками (сетевые запросы или ввод-вывод), лучше подходит асинхронное программирование с asyncio, позволяющее выполнять множество операций параллельно.

Выводы

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

Если вы хотите глубже разобраться в этой теме и освоить другие аспекты Python, обратите внимание на курс от ProductStar. Освойте востребованную профессию и начните зарабатывать в среднем 200 000 ₽ на удаленке. Преподаватели курса — опытные практики из «Яндекса», Ozon и Amazon.

Комментарии

Нажимая кнопку «Получить консультацию», вы подтверждаете согласие на обработку персональных данных в соответствии с условиями Политики конфиденциальности

Проконсультируйтесь
с карьерным специалистом

Проанализируем ваши навыки, сферу интересов и дадим рекомендации по дальнейшему профессиональному развитию

Вам может понравиться

3
дн.
час.
мин.
сек.
:
00
:
00
:
00
скидка до 57% и подарки на 135 000 ₽
Что такое многопоточность в Python? Многопоточность в Python — способ сделать так, чтобы программа могла выполнять сразу несколько задач одновременно. Например, пока одна задача считает числа, другая может подгружать данные из базы. Для этого создаются потоки (threads) — как дополнительные инструменты, которые работают внутри программы. Пример применения многопоточности: Онлайн-магазин одновременно обрабатывает заказы, обновляет информацию о наличии товаров на складе и отправляет уведомления пользователям. Программа для мониторинга серверов собирает данные о нагрузке и доступности из разных регионов, обновляя дашборд в реальном времени. Что такое поток? Это небольшая самостоятельная часть программы, которая выполняет конкретную задачу. Все threads работают в рамках одной программы, но каждая из них действует как отдельный исполнитель, параллельно с другими. Представьте многозадачного робота в мастерской. У него несколько рук: одна рука паяет микросхемы, другая собирает корпус устройства, а третья проверяет готовые изделия. Каждая рука работает одновременно, но все они управляются одним «центральным процессором» — роботом. Это и есть работа потоков: они делят задачи, но координируются в рамках одной программы. Где это полезно в программировании? Один thread может скачивать большой файл, пока другой — обрабатывает уже загруженные данные. В чат-приложении один поток отправляет сообщения на сервер, а другой — обновляет интерфейс. Пример: import threading def count_down(start): """ Отсчитывает числа от заданного значения до 1. """ for i in range(start, 0, -1): print(f"Countdown: {i}") # Создаем два потока с разным начальным значением отсчета thread1 = threading.Thread(target=count_down, args=(5,)) thread2 = threading.Thread(target=count_down, args=(3,)) # Запускаем потоки thread1.start() thread2.start() # Ожидаем завершения thread1.join() thread2.join() print("Отсчет завершен.") Здесь функция count_down выполняет простой обратный отсчет чисел от заданного значения до 1. Первый считает от 5 до 1, второй считает от 3 до 1. Как сделать многопоточность в Python? Для создания и управления потоками в Python используется специальный модуль threading. Вместо того чтобы делать задачи по очереди, программа справляется с ними параллельно, экономя время. Чтобы создать поток, выполните следующие шаги: Определите функцию, которая будет выполнять задачу. Передайте эту функцию в класс Thread через параметр target. Если функция принимает аргументы, передайте их с помощью параметра args в виде кортежа. Запустите поток с помощью метода start(). Дождитесь завершения с помощью метода join(). Пример: import threading def count_words(filename): """ Считает количество слов в файле и выводит результат. """ try: with open(filename, "r") as file: text = file.read() word_count = len(text.split()) print(f"{filename}: {word_count} слов") except FileNotFoundError: print(f"{filename}: файл не найден") # Создаем два потока для работы с разными файлами thread1 = threading.Thread(target=count_words, args=("file1.txt",)) thread2 = threading.Thread(target=count_words, args=("file2.txt",)) # Запускаем потоки thread1.start() thread2.start() # Ожидаем завершения thread1.join() thread2.join() print("Обработка файлов завершена.") Синхронизация потоков Когда несколько threads выполняются одновременно и обращаются к одной и той же части программы или общим данным, могут возникнуть ошибки. Представьте, что два человека пытаются одновременно писать на одной доске: их записи могут пересекаться, и результат будет неразборчивым. В программировании эта проблема называется «состояние гонки» (race condition). Чтобы предотвратить такие ситуации, используется синхронизация потоков — метод, который управляет доступом потоков к общим ресурсам, чтобы они не мешали друг другу. В Python для этого используется специальный инструмент — Lock (замок), который предоставляет модуль threading. Как это работает? Представим, что общий ресурс — это комната, а потоки — люди, которые хотят войти. Замок (Lock) закрывает дверь, чтобы только один человек мог войти в комнату за раз. Другие потоки (люди) ждут за дверью, пока текущий поток не выйдет (замок откроется). Что такое ThreadPoolExecutor и чем он поможет? Это инструмент, который позволяет выполнять несколько задач одновременно с использованием пула threads. Вы создаете группу потоков (например, 3 или 5), и задачи распределяются между ними автоматически. Например, у вас есть программа, которая скачивает 50 файлов из интернета. Если вы начнете скачивать их один за другим, это займет много времени. Но если вы скачаете сразу несколько файлов параллельно, то будет быстрее. Именно для таких задач и нужен ThreadPoolExecutor. Пример использования: from concurrent.futures import ThreadPoolExecutor def process_file(file_name): print(f"Processing file: {file_name}") # Создаем пул из 3 threads with ThreadPoolExecutor(max_workers=3) as executor: files = ["file1.txt", "file2.txt", "file3.txt", "file4.txt"] executor.map(process_file, files) Все файлы обрабатываются параллельно, ускоряя выполнение программы. Что есть помимо потоков в Python? Для решения задач параллельного выполнения Python предлагает не только потоки. Существуют и другие подходы, которые эффективно справляются с ограничениями многопоточности, помогая обрабатывать данные быстрее и проще. Если в питон многопоточность ограничена GIL (глобальной блокировкой интерпретатора), используйте модуль multiprocessing, который создает независимые процессы и задействует все ядра процессора — это идеально для ресурсоемких вычислений. Для задач с задержками (сетевые запросы или ввод-вывод), лучше подходит асинхронное программирование с asyncio, позволяющее выполнять множество операций параллельно. Выводы В этой статье мы разобрали, есть ли многопоточность в Python, как она работает, какие инструменты доступны, а также изучили примеры ее применения. Многопоточность в Python открывает широкие возможности для параллельного выполнения задач, но для полной оптимизации программ важно понимать ограничения GIL, уметь правильно синхронизировать потоки и выбирать подходящие инструменты. Если вы хотите глубже разобраться в этой теме и освоить другие аспекты Python, обратите внимание на курс от ProductStar. Освойте востребованную профессию и начните зарабатывать в среднем 200 000 ₽ на удаленке. Преподаватели курса — опытные практики из «Яндекса», Ozon и Amazon.