Привет всем! Сегодня — небольшой пост, посвященный вопросу «Работа с потоками в Python». Ну и конечно — пример кода для работы с потоками 🙂 Надеюсь — будет полезно.
Итак, что такое потоки в Python? Python использует потоки для реализации многозадачности. Потоки позволяют запускать несколько команд или задач одновременно и манипулировать ими, не останавливая выполнение других задач. ЗАчем это нужно? Ну, например — это может быть полезно, при работе с сетью или многомерными данными, где необходимо выполнять несколько операций одновременно и обрабатывать результаты параллельно.
Теперь пример работы с потоками. Будем выводить результат вычислений числа Фибоначчи (можно что-то другое, но сейчас в голову не приходит ничего больше из того, что может заставить компьютер сильно задуматься). Естественно — мы будем смотреть на время, в течении которого выполняется код. Для этого и нужна библиотека time. Итак, вывод числа Фибоначчи для, например, числа 40:
import time
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
start = time.time()
print('Результат: ', fibonacci(40))
end = time.time()
result = end - start
print('Начало работы: ', start)
print('Конец работы: ', end)
print('Код работал: ', result, 'секунд')
Получаем результат:
Результат: 102334155
Начало работы: 1674906951.9962122
Конец работы: 1674907029.9873629
Код работал: 77.99115061759949 секунд
Это для понимания того, что задача ого-го какая ресурсоемкая для компьютера...
Ок, а теперь изменим код так, что бы он считал числа Фибоначчи в промежутке от 1 до 30:
import time
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
start = time.time()
for i in range(1, 31):
print('Для числа', i, ':', fibonacci(i))
# print('результат: ', fibonacci(i))
end = time.time()
result = end - start
print('Код работал ', result, 'секунд')
После чего получаем результат:
Для числа 1 : 1
Для числа 2 : 1
Для числа 3 : 2
Для числа 4 : 3
Для числа 5 : 5
Для числа 6 : 8
Для числа 7 : 13
Для числа 8 : 21
Для числа 9 : 34
Для числа 10 : 55
Для числа 11 : 89
Для числа 12 : 144
Для числа 13 : 233
Для числа 14 : 377
Для числа 15 : 610
Для числа 16 : 987
Для числа 17 : 1597
Для числа 18 : 2584
Для числа 19 : 4181
Для числа 20 : 6765
Для числа 21 : 10946
Для числа 22 : 17711
Для числа 23 : 28657
Для числа 24 : 46368
Для числа 25 : 75025
Для числа 26 : 121393
Для числа 27 : 196418
Для числа 28 : 317811
Для числа 29 : 514229
Для числа 30 : 832040
Код работал 1.2446682453155518 секунд
Прекрасно! А теперь представим, что нам нужно (кто его знает, зачем, но нужно) - считать числа Фибоначчи одновременно. Если мы запустим выполнение задачи в цикле (например, 10 раз подряд) - т.е. считаем числа от 1 до 30 первый раз - то тратим 1,24 секунд. Считаем второй раз - опять 1,24 секунд. Каждый следующий проход увеличивает время на те же самые плюс-минус 1,24 секунд.
Посмотрите на код, который демонстрирует данную возможность:
import time
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
start = time.time()
for x in range(1, 11):
print('Проход: ', x)
for i in range(1, 31):
print('Для числа', i, ':', fibonacci(i))
end = time.time()
result = end - start
print('Код работал ', result, 'секунд')
И теперь результат:
Код работал 14.41745662689209 секунд
А что, если начать использовать потоки?
Давайте попробуем (комментарии к коду - внутри):
#Импортируем модули threading и time, которые будем использовать для создания и запуска потоков, а так #же для измерения времени выполнения.
import threading
import time
#Эта функция вычисляет число Фибоначчи для данного индекса n.
def fibonacci(n):
if n <= 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n - 1) + fibonacci(n - 2)
#Эта функция будет исполняться в каждом потоке. Выводит сообщение о том, что поток работает, затем #использует функцию fibonacci() для вычисления и вывода чисел Фибоначчи для индексов от 1 до 30.
def thread_func(i):
print(f'Поток {i} работает...')
for i in range(1, 31):
print('Для числа', i, ':', fibonacci(i))
#Запоминаем время начала работы
start = time.time()
#Создаем 10 потоков, каждый из которых будет исполнять функцию thread_func. Эта функция печатает #сообщение о том, что поток работает, а затем исполняет цикл от 1 до 30 и для каждого числа вызывает #функцию fibonacci, которая находит числа Фибоначчи для этого числа и выводит результат на экран. После #создания всех потоков, программа засекает время и выводит начальное и конечное время, а также разницу #между ними, чтобы определить, сколько времени заняла работа программы.
threads = []
for i in range(10):
t = threading.Thread(target=thread_func, args=(i,))
threads.append(t)
t.start()
for thread in threads:
thread.join()
end = time.time()
result = end - start
print('Начало: ', start)
print('Конец: ', end)
print('Код работал ', result, 'секунд')
Итак, код с потоками имеется, и он - после выполнения - показывает следующие результаты работы программы:
Код работал 12.041714906692505 секунд
что на 2 секунды быстрее, если бы мы повторяли цикл раз за разом (напомню, что выполнение одного цикла у нас занимало 14 с копейками секунд.
Вот... надеюсь, вам стало немного проще разобраться с потоками в Python и как с ними работать. Как всегда - в случае возникновения вопросов пишите в Telegram или на почту 😉
Support the Blog!
Running a blog takes a lot of effort, time, and passion. Your donations help improve the content, inspire new ideas, and keep the project going.
If you’ve enjoyed the blog’s materials, any support would mean the world to me. Thank you for being here! ❤️