Python - Основной поток

Привет, молодые программисты! Сегодня мы отправляемся в захватывающее путешествие по миру потоков в Python, сосредоточившись на основном потоке. Как ваш добрый сосед-преподаватель информатики, я здесь, чтобы провести вас через эту увлекательную тему. Не волнуйтесь, если вы новичок в программировании – мы начнем с основ и постепенно будем развиваться. Так что возьмите свой любимый напиток, устроитесь комфортно и погружайтесь в науку!

Python - Main Thread

Что такое основной поток?

Перед тем как погружаться в детали, давайте понимать, что такое поток. Представьте себе, что вы читаете книгу, слушая музыку. Ваш мозг выполняет две задачи одновременно – это похоже на то, как работают потоки в программировании. Основной поток – это как основная сюжетная линия вашей программы, та, которая начинается при запуске вашего скрипта на Python.

Основной поток в действии

Давайте начнем с простого примера, чтобы увидеть основной поток в действии:

import threading
import time

def print_current_thread():
print(f"Текущий поток: {threading.current_thread().name}")

print_current_thread()
time.sleep(2)
print("Основной поток все еще работает!")

Когда вы запустите этот скрипт, вы увидите что-то вроде:

Текущий поток: MainThread
Основной поток все еще работает!

В этом примере мы используем модуль threading, чтобы получить информацию о текущем потоке. Функция time.sleep(2) просто добавляет небольшую паузу, как драматическая ellipsis в нашей программной истории.

Доступ к основному потоку

Теперь, когда мы увидели основной поток в действии, давайте научимся получать к нему прямой доступ. Python предоставляет нам удобный способ сделать это:

import threading

main_thread = threading.main_thread()
print(f"Имя основного потока: {main_thread.name}")
print(f"ID основного потока: {main_thread.ident}")

Этот скрипт выведет что-то вроде:

Имя основного потока: MainThread
ID основного потока: 140735268892672

ident – это уникальный идентификатор потока. Это как социальный страховой номер для потоков – ни два потока не будут иметь одинаковый ID.

Проверка, работаем ли мы в основном потоке

Иногда вам может понадобиться проверить, выполняется ли ваш код в основном потоке. Вот как вы можете это сделать:

import threading

def am_i_main():
return threading.current_thread() == threading.main_thread()

print(f"Мы в основном потоке? {am_i_main()}")

def not_main():
print(f"Мы теперь в основном потоке? {am_i_main()}")

thread = threading.Thread(target=not_main)
thread.start()
thread.join()

Этот скрипт выведет:

Мы в основном потоке? True
Мы теперь в основном потоке? False

В этом примере мы создаем новый поток, который выполняет функцию not_main(). Когда мы вызываем am_i_main() из этого нового потока, он возвращает False.

Поведение основного потока в Python

Основной поток в Python имеет некоторые интересные особенности, которые важно понять. Давайте их исследуем!

Основной поток и завершение программы

Одна из ключевых особенностей основного потока заключается в том, что когда он заканчивает выполнение, вся программа Python обычно завершается. Давайте увидим это на практике:

import threading
import time

def long_task():
print("Начало длительной задачи...")
time.sleep(5)
print("Длительная задача завершена!")

thread = threading.Thread(target=long_task)
thread.start()

print("Основной поток завершен!")

Если вы запустите этот скрипт, вы, скорее всего, увидите:

Начало длительной задачи...
Основной поток завершен!

Заметьте, что сообщение "Длительная задача завершена!" никогда не появится. Это происходит потому, что основной поток завершился, и программа завершилась, прежде чем длительная задача смогла завершиться.

Демон-потоки против не-демон-потоков

Чтобы лучше понять поведение основного потока, нам нужно поговорить о демон-потоках. Демон-поток – это как фоновая задача, которая не мешает программе завершиться. Давайте модифицируем наш предыдущий пример:

import threading
import time

def long_task():
print("Начало длительной задачи...")
time.sleep(5)
print("Длительная задача завершена!")

thread = threading.Thread(target=long_task)
thread.daemon = True  # Установите поток как демон
thread.start()

print("Основной поток завершен!")

Вывод будет тем же, что и раньше. Однако, если мы удалим строку thread.daemon = True, мы увидим:

Начало длительной задачи...
Основной поток завершен!
Длительная задача завершена!

Это происходит потому, что не-демон-потоки (по умолчанию) предотвращают завершение программы до их завершения.

Основной поток ждет других потоков

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

import threading
import time

def task(name):
print(f"Задача {name} начата...")
time.sleep(2)
print(f"Задача {name} завершена!")

threads = []
for i in range(3):
t = threading.Thread(target=task, args=(f"T{i}",))
threads.append(t)
t.start()

for t in threads:
t.join()

print("Все задачи выполнены!")

Этот скрипт выведет:

Задача T0 начата...
Задача T1 начата...
Задача T2 начата...
Задача T0 завершена!
Задача T1 завершена!
Задача T2 завершена!
Все задачи выполнены!

Метод join() заставляет основной поток подождать, пока каждый поток не завершит свою работу.

таблица полезных методов потоков

Вот таблица некоторых полезных методов потоков, о которых мы обсуждали, и еще нескольких:

Метод Описание
threading.current_thread() Возвращает текущий объект Thread
threading.main_thread() Возвращает основной объект Thread
Thread.start() Начинает деятельность потока
Thread.join() Ждет завершения потока
Thread.is_alive() Возвращает, жив ли поток
Thread.setDaemon(bool) Устанавливает демон-флаг потока

Заключение

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

Заканчивая, я вспоминаю цитату знаменитого информатика Алана Кэя: "Лучший способ предсказать будущее – это изобрести его." С вашим новым знанием потоков Python, вы теперь оборудованы, чтобы изобрести некоторые удивительные многопоточные программы!

Продолжайте программировать, учитесь и, что самое важное, наслаждайтесь! До следующего раза, счастливого потокования!

Credits: Image by storyset