Начнем с определения потока, поток - это не что иное, как легкий процесс. Они обычно присутствуют внутри процесса и совместно используют память и состояние процесса. Таким образом, в многопоточности мы можем выполнять несколько потоков одновременно.
Но вот и идет GIL, здесь мы не будем это подробно обсуждать. Но, попросту говоря, GIL позволяет одновременно запускать только один поток. Теперь вы, должно быть, думаете, что в таком случае многопоточность, когда мы можем запускать только один поток за раз?
Итак, прежде чем ответить на вышеуказанный вопрос, мы должны понять, что задача, которую мы выполняем в системе, бывает двух типов: с привязкой к ЦП или с привязкой к вводу-выводу. например, умножение больших матриц ограничено ЦП, но запрос веб-страницы с веб-сервера ограничен вводом-выводом. Многопоточность в Python полезна при выполнении задач, связанных с вводом-выводом. В задачах с привязкой к ЦП GIL не снимает блокировку до тех пор, пока задача не будет завершена, но в задаче с привязкой к вводу-выводу, как только потоки запускаются из-за ожидания некоторого ввода-вывода, GIL может снять свою блокировку.
Приведенный ниже код демонстрирует возможности многопоточности в задаче с привязкой к вводу-выводу.
import datetime import threading import requests def io_bound_task(url): resp = requests.get(url) print("Received Response", resp.status_code) def sequential(url): # call the function sequentially 5 times. start_time = datetime.datetime.now() for i in range(5): io_bound_task(url) time_elapsed = datetime.datetime.now() - start_time print("Time Elapsed using normal sequential method", time_elapsed) return time_elapsed def threader(url): # call the function in 5 separate threads. threads = [] start_time = datetime.datetime.now() for i in range(5): # Create a new thread, assign it the worker function, and the argument for it p = threading.Thread(target=io_bound_task, args=(url,)) p.start() # Start the thread threads.append(p) # Add it to list of threads for thread in threads: thread.join() # wait for all the threads to finish time_elapsed = datetime.datetime.now() - start_time print("Time Elapsed using multi threading", time_elapsed) return time_elapsed if __name__ == "__main__": url = "https://www.spotify.com" normal_time = sequential(url) threading_time = threader(url) print("Improvement percent", int((normal_time - threading_time) / normal_time * 100)) # Improvement percent 87 # Process finished with exit code 0
Как видите, мы видим значительное улучшение в многопоточной версии.
Теперь обратитесь к следующему примеру выполнения задачи, связанной с процессором.
import datetime import threading import requests def cpu_bound_task(number): sum = 0 for i in range(number): sum += i print(sum) return sum def sequential(number): # call the function sequentially 5 times. start_time = datetime.datetime.now() for i in range(5): cpu_bound_task(number) time_elapsed = datetime.datetime.now() - start_time print("Time Elapsed using normal sequential method", time_elapsed) return time_elapsed def threader(number): # call the function in 5 separate threads. threads = [] start_time = datetime.datetime.now() for i in range(5): # Create a new thread, assign it the worker function, and the argument for it p = threading.Thread(target=cpu_bound_task, args=(number,)) p.start() # Start the thread threads.append(p) # Add it to list of threads for thread in threads: thread.join() # wait for all the threads to finish time_elapsed = datetime.datetime.now() - start_time print("Time Elapsed using multi threading", time_elapsed) return time_elapsed if __name__ == "__main__": number = 50000000 normal_time = sequential(number) threading_time = threader(number) print("Improvement percent", int((normal_time - threading_time) / normal_time * 100)) # Improvement percent 7
Итак, я надеюсь, что теперь вы получили общее представление о том, когда многопоточность полезна.
* Примечание. В этом блоге не подробно рассказывается о том, как работает GIL, это скорее руководство для начинающих по многопоточности и ее использованию.
Пожалуйста, поделитесь своими комментариями, приветствиями и приятным обучением. Прощай.