Поток — это единица выполнения внутри процесса. Многопоточность означает одновременное выполнение нескольких потоков путем быстрого переключения управления ЦП между потоками (так называемое переключение контекста ).
Python Global Interpreter Lock ограничивает одновременный запуск одного потока, даже если машина содержит несколько процессоров.
Коды
Создание потоков
В следующем фрагменте кода показано, как создавать потоки с помощью модуля threading
в Python:
# импортируем модуль потоковой передачи import threading # импортируем time module import time # Функция для печати "Hel lo ", однако функция засыпает # на 2 секунды на 11-й итерации. def print_hello (): for i in range (20): if i == 10: time.sleep (2) print (" Hello ") # Функция для печати числа до заданного numberdef print_numbers (num): for i in range (num + 1): print (i) # Создание потоков. В качестве цели установлено имя # функции, которая должна быть выполнена внутри потока, а # args - аргументы, которые должны быть переданы функции, которую # необходимо выполнить. Print ("Приветствие из основного потока.") Thread1 = threading.Thread (target = print_hello, args = ()) thread2 = threading.Thread (target = print_numbers, args = (10,)) # Запуск двух потоков sthread1.start () thread2.start () print ("Это основной поток снова! ")
Давайте попробуем разобраться в вывод путем отслеживания выполнения кода:
- Выполняется основной поток. «Приветствие из основного потока» печатается, потоки
thread1
иthread2
создаются и запускаются. - Происходит переключение контекста , и
thread1
начинает выполнение. - После первых десяти итераций
thread1
переходит в спящий режим, аthread2
начинает выполнение и завершается до следующего переключения контекста. - Теперь основной поток получает контроль над ЦП и печатает: «Это снова основной поток!»
- Происходит еще одно переключение контекста, и
thread2
возобновляет выполнение и завершает работу. - Поскольку больше нет инструкций для выполнения основным потоком, программа завершается.
Использование thread.join ()
Что, если бы требовалось заблокировать основной поток до thread1
и thread2
закончили выполнение? Тогда может пригодиться thread.join ()
, поскольку он блокирует вызывающий поток до тех пор, пока поток, чей метод join () не будет завершен, не будет завершен:
# импорт модуля потоковой передачи import threading # importing время импорта модуля времени # Функция для печати "Hello", однако функция "спит" # на 2 секунды на 11-й итерации. def print_hello (): for i in range (20): if i == 10: time.sleep (2) print ("Hello") # Функция для печати чисел до заданного числа. def print_numbers (num): for i in range (num + 1): print (i) # Создание потоков. В качестве цели задается имя # функции, которая должна выполняться внутри потока, а # args - аргументы, которые должны быть переданы функции, которую # необходимо выполнить. Print ("Приветствие из основного потока.") Thread1 = threading.Thread (target = print_hello, args = ()) thread2 = threading.Thread (target = print_numbers, args = (10,)) # Запуск двух потоков sthread1.start () thread2.start () thread1.join () thread2 .join () print («Это снова главный поток!») print («Потоки 1 и 2 завершили выполнение.»)