Многопоточность и многопроцессорность в Python
Поток — это наименьшая единица программы или процесса, выполняемая независимо или по расписанию операционной системой. В компьютерной системе операционная система выполняет многозадачность, разделяя процесс на потоки.
Поток — это легкий процесс, который обеспечивает выполнение отдельного процесса в системе. В Python 3, когда в программе работают несколько процессоров, каждый процессор работает одновременно, чтобы выполнять свои задачи по отдельности.
Давайте разберемся, что такое многопоточность и многопроцессорность в Python 3.
Что такое многопоточность в Python?
Многопоточность в Python — это метод в программировании на Python, позволяющий одновременно запускать несколько потоков за счет быстрого переключения между ними с помощью процессора (так называемое переключение контекста).
Кроме того, он позволяет совместно использовать свое пространство данных с основными потоками внутри процесса, которые обмениваются информацией с другими потоками проще, чем с отдельными процессами. Многопоточность направлена на одновременное выполнение нескольких задач, что увеличивает производительность, скорость и улучшает визуализацию приложения.
Примечание. Глобальная блокировка интерпретатора Python(GIL) позволяет запускать один поток за раз, даже если машина имеет несколько процессоров.
Преимущества
Ниже приведены преимущества создания многопоточного приложения на Python:
- Это обеспечивает эффективное использование ресурсов компьютерной системы.
- Многопоточные приложения более отзывчивы.
- Разделяет ресурсы и свое состояние с подпотоками, что делает его более экономичным.
- Делает многопроцессорную архитектуру более эффективной за счет схожести.
- Экономит время за счет одновременного выполнения нескольких потоков.
- Системе не требуется слишком много памяти для хранения нескольких потоков.
Когда используется?
Это очень полезный метод для экономии времени и повышения производительности приложения. Многопоточность позволяет программисту разделять задачи приложения на подзадачи и одновременно запускать их в программе.
Это позволяет потокам обмениваться данными и совместно использовать ресурсы, такие как файлы, данные и память, одному и тому же процессору. Кроме того, это увеличивает скорость отклика пользователя, чтобы продолжить выполнение программы, даже если часть приложения имеет длину или заблокирована.
Как добиться многопоточности в Python?
Для обработки потоков в Python используются два основных модуля многопоточности:
Модули потоков
В Python 3 метод thread обозначен как устаревший, переименован и доступен как _thread, который поддерживает обратную совместимость.
thread.start_new_thread( function_name, args[, kwargs] )
Чтобы реализовать модуль потока в Python, нам нужно импортировать его, а затем определить функцию, которая выполняет какое-то действие, устанавливая цель с помощью переменной.
import thread # import the thread module import time # import time module def cal_sqre(num): # define the cal_sqre function print(" Calculate the square root of the given number") for n in num: time.sleep(0.3) # at each iteration it waits for 0.3 time print(' Square is : ', n * n) def cal_cube(num): # define the cal_cube() function print(" Calculate the cube of the given number") for n in num: time.sleep(0.3) # at each iteration it waits for 0.3 time print(" Cube is : ", n * n *n) arr = [4, 5, 6, 7, 2] # given array t1 = time.time() # get total time to execute the functions cal_sqre(arr) # call cal_sqre() function cal_cube(arr) # call cal_cube() function print(" Total time taken by threads is :", time.time() - t1) # print the total time
Calculate the square root of the given number Square is: 16 Square is: 25 Square is: 36 Square is: 49 Square is: 4 Calculate the cube of the given number Cube is: 64 Cube is: 125 Cube is: 216 Cube is: 343 Cube is: 8 Total time taken by threads is: 3.005793809890747
Модули потоковой передачи
Модуль потоковой передачи — это высокоуровневая реализация многопоточности, используемая для развертывания приложения на Python. Чтобы использовать многопоточность, нам нужно импортировать модуль threading в программу Python.
Методы | Описание |
---|---|
start() | Метод start() используется для инициирования активности потока. И он вызывается только один раз для каждого потока, чтобы можно было начать выполнение потока. |
run() | Метод run() используется для определения активности потока и может быть переопределен классом, расширяющим класс потоков. |
join() | Метод join() используется для блокировки выполнения другого кода до завершения потока. |
Выполните следующие шаги, чтобы реализовать модуль потоковой передачи в многопоточности Python:
1. Импортируйте модуль потоковой передачи.
Создайте новый поток, импортировав модуль потоковой передачи, как показано.
Модуль потоковой передачи состоит из класса Thread, который необходим для создания потока Python.
2. Объявление параметров потока: target функция, argument, and kwargs используются в качестве параметров класса Thread().
- Target: определяет имя функции, выполняемой потоком.
- Args: определяет аргументы, которые передаются имени целевой функции.
import threading def print_hello(n): print("Hello, how old are you ", n) t1 = threading.Thread( target = print_hello, args =(18, ))
В приведенном выше коде мы вызвали функцию print_hello() в качестве целевого параметра. Print_hello() содержит один параметр n, который передается в параметр args.
3. Запустите новый поток: чтобы запустить поток в многопоточности Python, вызовите объект класса потока. Метод start() может быть вызван один раз для каждого объекта потока; в противном случае возникает ошибка исключения.
4. Метод соединения: это метод join(), используемый в классе потока для остановки выполнения основного потока и ожидания полного выполнения объекта потока. Когда объект потока завершен, он запускает выполнение основного потока в Python.
import threading def print_hello(n): Print("Hello, how old are you? ", n) T1 = threading.Thread( target = print_hello, args =(20, )) T1.start() T1.join() Print("Thank you")
Hello, how old are you? 20 Thank you
Когда приведенная выше программа выполняется, метод join() останавливает выполнение основного потока и ждет, пока поток t1 не будет полностью выполнен. После успешного выполнения t1 основной поток начинает свое выполнение.
Примечание. Если мы не используем метод join(), интерпретатор может выполнить любой оператор печати внутри программы Python. Обычно он выполняет первый оператор печати, потому что интерпретатор выполняет строки кода с самого начала программы.
5. Синхронизация потоков в Python
Это механизм синхронизации потоков, который гарантирует, что никакие два потока не могут одновременно выполнять определенный сегмент внутри программы для доступа к общим ресурсам. Ситуацию можно назвать критическими участками. Мы используем состояние гонки, чтобы избежать состояния критического раздела, когда два потока не обращаются к ресурсам одновременно.
Напишем программу для использования модуля потоковой передачи в Python Multithreading.
import time # import time module import threading from threading import * def cal_sqre(num): # define a square calculating function print(" Calculate the square root of the given number") for n in num: # Use for loop time.sleep(0.3) # at each iteration it waits for 0.3 time print(' Square is : ', n * n) def cal_cube(num): # define a cube calculating function print(" Calculate the cube of the given number") for n in num: # for loop time.sleep(0.3) # at each iteration it waits for 0.3 time print(" Cube is : ", n * n *n) ar = [4, 5, 6, 7, 2] # given array t = time.time() # get total time to execute the functions #cal_cube(ar) #cal_sqre(ar) th1 = threading.Thread(target=cal_sqre, args=(ar, )) th2 = threading.Thread(target=cal_cube, args=(ar, )) th1.start() th2.start() th1.join() th2.join() print(" Total time taking by threads is :", time.time() - t) # print the total time print(" Again executing the main thread") print(" Thread 1 and Thread 2 have finished their execution.")
Calculate the square root of the given number Calculate the cube of the given number Square is: 16 Cube is: 64 Square is: 25 Cube is: 125 Square is: 36 Cube is: 216 Square is: 49 Cube is: 343 Square is: 4 Cube is: 8 Total time taken by threads is: 1.5140972137451172 Again executing the main thread Thread 1 and Thread 2 have finished their execution.