Comments 28
1. В питоне нет многопоточности в привычном понимании.
2. Использование потоков очень сильно замедляет выполнение программы.
Это так?
Для операций последовательного и параллельного (в тредах) скачивания файлов из интернета выигрывает конечно второй способ.
В некритичных приложениях потоки использовать вполне можно.
В критичных случаях используется наиболее эффективная асинхронная (не-б-б-б-б-блокирующая) модель, когда пускается несколько процессов с неблокирующим IO.
Чтобы вы не думали, что GIL появился с потолка, могу добавить, что его наличие в полтора-два раза ускоряет работу однопоточных приложений. Гвидо в свое время заявил, что GIL не уйдет до тех пор, пока не будет предложено решение, не снижающее производительность обыкновенных однопоточных программ.
Вот, я тоже читал, что GIL ускоряет работу однопоточных приложений, а почему?
Не ускоряет, а просто программа выполняется быстрее из-за отсутствия необходимости работать с запуском потоков и их синхронизацией.
Но ведь всё равно происходит смена контекста, сама ОС меняет его, правильно? Или я ошибаюсь, просто например, на однопоточной программе на C++ или на Python, не будет ни там, ни там синхронизаций? Не могу понять в чём здесь "эврика" python.
Речь идёт о потерях на то, что потокобезопасный код всё равно захватывает и освобождает блокировки, даже если он, в данный момент, работает в один поток.
К примеру, вывод print()
или опрос/установка исключений плавающей запятой. Скажем, в коде NumPy есть примечательный комментарий: "мы сначала опрашиваем маску исключений fegetexceptflag()
, а потом устанавливаем fesetexceptflag()
, если только нам нужна другая маска, поскольку опрос в 10-50 раз быстрее установки".
Так что GIL — скорее очередной повод попинать питон, нежели реальная проблема.
Тем более учитывая то, что в Unix создание процесса обходится очень дёшево.
Не помню кто, один из гуру C++, сказал, что даже после многих лет работы с потоками неспособен написать корректную многопоточную программу.
Вообще, это скорее дискуссия на тему процессы vs потоки :-)
А вообще я на практике однопоточным приложением в 2 раза убирал многопоточные при перемножении матриц на C
Про умножение — каким образом?
Просто нужно понимать ограничения и применимость подхода. Без знания специфики, вообще в многопоточное программирования лучше не соваться.
я выполнил Ваш скрипт (Тест производительности) своего ничего не дописывал, только копипаст:
выполнения скрипта без потоков:
real 1m45.761s
user 1m45.563s
sys 0m0.112s
выполнение скрипта с потоками:
real 0m12.954s
user 0m12.201s
sys 0m0.808s
это я что-то не так сделал или у меня неправильная машина?
ubuntu, intel core2duo работают 2 ядра
может все-таки в маке дело?
www.dabeaz.com/python/NewGIL.pdf
последовательный запуск — 10.447758279 с
параллельный запуск — 10.4375156 с
На моей машине получается то же, что у автора. Питон 3.6, Ubuntu, Intel i7 2.8 GHz.
MacOS 10.14.5, Intel Core I5 2.3Ghz
Python 2.7.10
Последовательно 5.6 сек
Параллельно 7.6 сек
Python 3.7.3
Последовательно 10.9 сек
Параллельно 10.4 сек
Python2 рулит?
habr.com/ru/company/otus/blog/458694
«Одной из особенностей CPython 3.8, является PEP554, реализация субинтерпретаторов и API с новым модулем interpreters в стандартной библиотеке.
Это позволяет создавать несколько интерпретаторов из Python в рамках одного процесса. Еще одно нововведение Python 3.8 заключается в том, что все интерпретаторы будут иметь свои собственные GIL.»
Интересно как теперь по скорости.
Как устроен GIL в Python