@Автор: Рансен
На самом деле, еще одна очень важная тема многопоточности в Python называетсяGIL(Global Interpreter Lock, то есть глобальная блокировка интерпретатора).
Многопоточность не обязательно быстрее, чем однопоточность
В Python многозадачность может быть достигнута за счет многопроцессорности, многопоточности и многозадачности. Обязательно ли многопоточность быстрее, чем однопоточность?
Ниже я использую фрагмент кода, чтобы доказать свою точку зрения.
'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''
import threading, time
def my_counter():
i = 0
for _ in range(100000000):
i = i+1
return True
def main1():
start_time = time.time()
for tid in range(2):
t = threading.Thread(target=my_counter)
t.start()
t.join() # 第一次循环的时候join方法引起主线程阻塞,但第二个线程并没有启动,所以两个线程是顺序执行的
print("单线程顺序执行total_time: {}".format(time.time() - start_time))
def main2():
thread_ary = {}
start_time = time.time()
for tid in range(2):
t = threading.Thread(target=my_counter)
t.start()
thread_ary[tid] = t
for i in range(2):
thread_ary[i].join() # 两个线程均已启动,所以两个线程是并发的
print("多线程执行total_time: {}".format(time.time() - start_time))
if __name__ == "__main__":
main1()
main2()
результат операции
单线程顺序执行total_time: 17.754502773284912
多线程执行total_time: 20.01178550720215
Боюсь, вы скажете, что я могу получить результаты из хаоса, я лучше сделаю снимок, чтобы увидеть это ясно
В это время я сомневаюсь: моя машина вышла из строя? На самом деле это не так, по сути Python thread недействителен, не играл в параллельные вычисления.
Потоки Python инкапсулируют базовые потоки операционной системы.Pthread(полное имяPOSIX Thread), в то время как в Windows этоWindows Thread. Кроме того, потоки Python также полностью управляются операционной системой, например, координируя время выполнения, управляя ресурсами памяти, управляя прерываниями и так далее.
GIL не является функцией Python
Концепция GIL объясняется простым предложением, то естьОдин интерпретатор CPython может одновременно выполнять только один байт-код, независимо от количества потоков.. Что следует отметить в отношении этого определения:
Первое, что должно быть ясно, это то, чтоGIL не является функцией Python, концепция, появившаяся при реализации синтаксического анализатора Python (CPython).
C++ представляет собой набор стандартов языка (синтаксиса), но может быть скомпилирован в исполняемый код с помощью различных компиляторов. Известные компиляторы, такие как GCC, INTEL C++, Visual C++ и т. д.
То же самое верно и для Python: один и тот же фрагмент кода может выполняться в разных средах выполнения Python, таких как CPython, PyPy и Psyco.
Другие интерпретаторы Python не обязательно имеют GIL.. Например, Jython (JVM) и IronPython (CLR) не имеют GIL, а CPython, PyPy имеют GIL;
Потому что CPython является средой выполнения Python по умолчанию в большинстве сред. Поэтому в представлении многих людей CPython — это Python, и считается само собой разумеющимся, что GIL относят к недостаткам языка Python. Итак, давайте проясним здесь:GIL не является особенностью Python, Python может быть полностью независимым от GIL.
GIL по сути является мьютексом
Суть GIL - блокировка взаимного исключения. Поскольку это блокировка взаимного исключения, суть всех блокировок взаимного исключения одинакова. Все они превращают параллельную операцию в последовательную, чтобы контролировать, что общие данные могут быть изменены только одним задача одновременно. , тем самым обеспечивая безопасность данных.
Одно можно сказать наверняка: для защиты безопасности разных данных вы должны добавлять разные блокировки.
GIL работает: например, на картинке ниже показан рабочий пример GIL в программах на Python. Который, по очереди выполняя поток 1, 2, 3, в начале выполнения каждого потока будет блокировать GIL, чтобы предотвратить выполнение других потоков; то же самое, каждый поток после некоторого времени выполнения освобождает GIL, чтобы разрешить другому потоку начать использование ресурсов.
вычислительно интенсивный
Задачи с интенсивными вычислениями характеризуются большим количеством вычислений, потребляющих ресурсы ЦП.
Давайте начнем с простого примера с интенсивными вычислениями:
'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''
import time
COUNT = 50_000_000
def count_down():
global COUNT
while COUNT > 0:
COUNT -= 1
s = time.perf_counter()
count_down()
c = time.perf_counter() - s
print('time taken in seconds - >:', c)
time taken in seconds - >: 9.2957003
Это один поток, время 9 секунд, давайте используем два потока, чтобы увидеть результат:
'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''
import time
from threading import Thread
COUNT = 50_000_000
def count_down():
global COUNT
while COUNT > 0:
COUNT -= 1
s = time.perf_counter()
t1 = Thread(target=count_down)
t2 = Thread(target=count_down)
t1.start()
t2.start()
t1.join()
t2.join()
c = time.perf_counter() - s
print('time taken in seconds - >:', c)
time taken in seconds - >: 17.110625
Основная операция нашей программы это расчет, ЦП не ждет, а после перехода на многопоточность, после добавления потоков, частое переключение между потоками увеличивает накладные расходы, а время конечно увеличится.
Другой тип — интенсивный ввод-вывод.Все задачи, связанные с сетевым и дисковым вводом-выводом, являются задачами, интенсивными вводом-выводом.Этот тип задач характеризуется очень небольшим потреблением ЦП, и большую часть времени задача ожидает завершения операции ввода-вывода (поскольку Скорость ввода-вывода намного ниже, чем скорость процессора и памяти). Для задач с интенсивным вводом-выводом чем больше задач, тем выше эффективность ЦП, но есть предел. Наиболее распространенными задачами являются задачи с интенсивным вводом-выводом, такие как веб-приложения.
Резюме: Для IO-интенсивной работы (Python Crawler) многопоточность может значительно улучшить эффективность кода. Для CPU-интенсивных вычислений (анализ данных Python, машинное обучение, глубокое обучение), многопотока может быть немного менее эффективной, чем однопоточная. Следовательно, в поле данных нет такой вещи, как многопоточь для повышения эффективности, но только путем обновления процессора в GPU и TPU для улучшения вычислительной мощности.
Ссылаться на:Колонка Python «Время гиков»~
Эта статья была включена в GitHub,Портал~, а также полноценные тестовые сайты для интервью с крупными производителями Добро пожаловать в Star.