Освоение параллельного выполнения в Python: подробное руководство
Вы когда-нибудь задумывались, как сложные симуляции заканчиваются так быстро или как огромные массивы данных обрабатываются в кратчайшие сроки? Эта статья демистифицирует концепцию параллельного программирования в Python. Мы будем использовать простые функции, чтобы понять основные понятия. Благодаря параллелизму мы можем ускорить моделирование и эффективно решать задачи, требующие большого объема данных. Давайте погрузимся в увлекательный мир параллельного программирования!
Изучение многопоточности в Python
Первый метод достижения параллельного программирования — многопоточность. Он позволяет одновременно запускать несколько потоков выполнения в рамках одного процесса, обеспечивая одновременное выполнение различных задач. Модуль потоков Python облегчает это, управляя потоками и создавая их на более высоком уровне.
Пример многопоточности: практический подход
Чтобы понять модуль потоков, давайте запустим две простые параллельные функции, которые одновременно печатают 1 и 0. Давайте углубимся:
import threading from time import sleep def print_num(num): # function to print number for i in range(5): sleep(1) print(num)
- import threading: Эта строка импортирует модуль потоковой обработки в Python, который предоставляет функции для создания потоков и управления ими.
- from time import sleep : эта строка импортирует sleep функцию от time модуль. sleep Функция используется для введения задержек в выполнении программы.
- print_num(num) это функция, которая принимает один аргумент num и выводит его значение пять раз с задержкой в 1 секунду между каждым выводом.
После этого мы напишем нашу основную программу и будем использовать потоки для выполнения функции.
if __name__ =="__main__": # creating thread t1 = threading.Thread(target=print_num, args=(1,)) t2 = threading.Thread(target=print_num, args=(0,)) # starting thread 1 t1.start() # starting thread 2 t2.start() print("Threads are running") # join the threads with the main function t1.join() t2.join() print("Program finished")
- если имя == “основной“: Эта строка проверяет, выполняется ли код как основная программа.
- t1 = threading.Thread(target=print_num, args=(1,)) : Создает объект Thread с именем t1. Аргумент target указывает функцию, которая будет выполняться в новом потоке, и args аргумент предоставляет аргументы, которые будут переданы функции (мы передаем 1 в первом случае и 0 во втором).
Теперь у нас есть 2 потока t1 и t2, мы начнем выполнение с t1.start() и t2.start() . t1.join() и t2.join() ждет, пока потоки t1 и t2 соответственно завершат свое выполнение, прежде чем перейти к следующим командам.
Threads are running 1 0 1 0 1 0 1 0 1 0 Program finished
Программа создает два потока, которые одновременно печатают числа 1 и 0. В выводе мы видим, что наши потоки работали параллельно, что привело к шаблону из 1 и 0. Подробную информацию о многопоточности в python см. в разделе Многопоточность в python.
Погружение в многопроцессорность в Python
Переходя ко второму методу, у нас есть многопроцессорность, которая выводит параллельное программирование в Python на совершенно новый уровень. В то время как многопоточность позволяет одновременное выполнение в рамках одного процесса, многопроцессорность позволяет нам распределять задачи между несколькими процессами, используя всю мощь современных процессоров. питона multiprocessing Модуль предоставляет удобный способ создания процессов и управления ими.
Пример многопроцессорной обработки: практическое руководство
Мы можем понять multiprocessing модуль, используя его для выполнения print_num функция. Обе функции будут работать одновременно, демонстрируя мощь многопроцессорной обработки. Давайте начнем:
import multiprocessing from time import sleep def print_num(num): # function to print number for i in range(5): sleep(1) print(num)
- import multiprocessing : эта строка импортирует multiprocessing модуль, обеспечивающий поддержку параллельного выполнения задач.
- from time import sleep : импортирует sleep функцию от time модуль.
- print_num(num) это функция, которая принимает один аргумент num и выводит его значение пять раз с задержкой в 1 секунду между каждым выводом.
if __name__ =="__main__": # creating thread p1 = multiprocessing.Process(target=print_num, args=(1,)) p2 = multiprocessing.Process(target=print_num, args=(0,)) # starting process 1 p1.start() # starting process 2 p2.start() print("Processes are running") # join the process with the main function p1.join() p2.join() print("Program finished")
- если имя ==”основной“: Эта строка проверяет, выполняется ли код как основная программа.
- p1 = multiprocessing.Process(target=print_num, args=(1,)) : Эта строка создает Process объект называется p1 . target аргумент указывает функцию, которая будет выполняться в новом процессе, а args аргумент предоставляет аргументы, которые будут переданы в функцию. В этом случае, print_num является целевой функцией, и 1 аргумент, переданный ему. То же самое и в случае p2 с 0 в качестве аргумента.
- p1.start() и p2.start() приступает к выполнению p1 и p2 процессы.
- p1.join() и p2.join() подождите, пока их соответствующие процессы завершат свое выполнение, прежде чем перейти к следующей строке.
Processes are running 1 0 1 0 1 0 1 0 1 0 Program finished
Программа создает два процесса, которые одновременно печатают числа 1 и 0. В выводе мы видим, что наши процессы выполнялись параллельно, что привело к шаблону из 1 и 0. Это демонстрирует мощь многопроцессорной обработки в достижении параллельного выполнения. Дополнительные сведения о многопроцессорности см. в разделе Многопроцессорность в python.
Представляем модуль Concurrent.futures в Python
Теперь давайте рассмотрим наш третий метод достижения параллельного программирования в Python: concurrent.futures . Этот высокоуровневый модуль предоставляет мощный и интуитивно понятный интерфейс для одновременного выполнения задач, абстрагируясь от сложностей низкоуровневого управления потоками или процессами.
Concurrent.futures Пример:
Возможно, вы уже видели шаблон в использовании модулей, похожий поток использования concurrent.futures модуль. Откройте вашу IDE и начнем!
import concurrent.futures def function1(): for i in range(5): print(f'Function 1: ') return 'Function 1 done' def function2(): for i in range(5): print(f'Function 2: ') return 'Function 2 done'
- import concurrent.futures : эта строка импортирует concurrent.futures модуль, который предоставляет высокоуровневый интерфейс для асинхронного выполнения (параллельных) функций.
- function1() и function2() просто напечатайте имя их функции, за которым следуют числа в диапазоне 0-4, используя цикл for.
# Create a ThreadPoolExecutor executor = concurrent.futures.ThreadPoolExecutor() # Submit functions to the executor future1 = executor.submit(function1) future2 = executor.submit(function2) # Retrieve the results result1 = future1.result() result2 = future2.result() # Print the results print(result1) print(result2) # Shutdown the executor executor.shutdown()
- executor = concurrent.futures.ThreadPoolExecutor() : Эта строка создает ThreadPoolExecutor объект называется executor который отвечает за управление и выполнение представленных функций одновременно с использованием потоков.
- future1 = executor.submit(function1) : Эта строка представляет function1 исполнителю для выполнения и возвращает Future объект называется future1 , представляющий результат выполнения функции. То же самое делается для подачи function2 .
- result1 = future1.result() : Эта строка получает результат function1 позвонив в result метод на future1 объект. Эта строка будет заблокирована до завершения выполнения функции и получения результата. За этим следует result2 который извлекает результат function2 .
- executor.shutdown() : останавливает исполнителя, освобождая его ресурсы и останавливая выполнение всех ожидающих выполнения задач.
Function 1: 0 Function 1: 1 Function 2: 0 Function 1: 2 Function 2: 1 Function 1: 3 Function 2: 2 Function 1: 4 Function 2: 3 Function 2: 4 Function 1 done Function 2 done
Подобно тому, что мы видели в наших предыдущих двух методах, мы получили функции, работающие параллельно, как мы видим в выводе. Код выполняет две функции одновременно, используя исполнитель пула потоков. Функции печатают числа от 0 до 4 с префиксом, обозначающим имя функции. Наконец, результаты выполнения каждой функции распечатываются.
Заключение: Мастер параллельного выполнения в Python
Мы изучили модули многопоточности, многопроцессорности и concurrent.futures в Python, узнали, как выполнять задачи параллельно, повышать производительность и эффективно управлять параллельными задачами. Эти универсальные модули ускоряют выполнение задач, связанных с процессором или вводом-выводом, и упрощают асинхронные операции. Они обеспечивают гибкость, раскрывая потенциал параллелизма и параллелизма в наших программах на Python. Как вы будете использовать эти методы в своем следующем проекте Python?
Рекомендации