Комментарии 38
Как классно жить в современном мире!
То есть, лет через 6-9 (когда GIL удалят и из флагов, а его удалят!) приличный кусок маленьких проектов, которые авторы писали для себя, и выложили в сеть по доброте душевной, превратятся в тыкву, если тысячи людей за эти 6 лет не потратят дополнительный кусок своей жизни на переписывание проектов, которые им давно не интересны.
В то же время, мы понимаем, что если бы 15 лет назад (или когда там змея родилась?) послушали инженеров, а не маркетологов, усиленно напирающих на популярные, а не полезные фичи, то через 8 лет мы бы оказались в точке не хуже, чем та, где GIL сначала разработали, потратив кучу ресурсов, а потом удалили, потратив еще одну кучу.
Интересно, если суммировать все это время, сколько человеческих жизней, получается, убило одно недальновидное решение?
....
— Я ж тебя из под земли достану, и под землю закопаю!
— Но КПД — ноль? НОЛЬ??!!
....
© Кто‑то из КВН
Не удалят. Зачем?
Только, боюсь, noGIL решение будет некрасивым костылём. Как вижу "stop the world" так думаю "приплыли"
Есть же Питон версии 2, и 3, добавят версии 4. ;)
Куча кода регулярно ломается при обновлении мажорных (а иногда и минорных) версий популярных библиотек, для этого и придумали всякие requirements.txt, virtualenv, контейнеры и т.п.
А тут переписывают значимую часть ядра языка на горизонте нескольких мажорных версий (5+ лет)
Не вижу проблемы и повода для ворчания
как же не видите? Вот же она у вас, в самом начале текста:
Куча кода регулярно ломается
А как (и на какой платформе) сделать так, чтобы этого не случалось? (голый Си не предлагать - на нем уже линукс написан)
Не думаю. Много таких свистелок прямо таки тяжело используют потоки?
GIL сначала разработали, потратив кучу ресурсов, а потом удалили, потратив еще одну кучу
мне кажется, "разрабатывать GIL" было не сложно, не ресурсоемко. Это простой, тупой и надежный ограничитель от "всего сложного и опасного".
Конечно, все сложное и опасное лучше разруливать как-то безопасно, но это сложно. Поэтому GIL выглядит как простое и надежное, кондовое такое временное решение, которое рано или поздно должно быть заменено. Но на первое время - "сойдет для сельской местности".
Аналогия: вы строите большой и сложный дом и вы не хотите, чтобы он сгорел из-за пожара в проводке. Сделать всю электрику по уму - долго, дорого и сложно. Поэтому для начала вы просто делаете один рубильник, который отрубает дом от электричества. Просто и надежно. И пока рубильник отключен - у вас дома уж точно проводка не загорится.
Но когда-то вы сделаете все сложные расчеты по проводке, подберете автоматы, лампы, плиту и щиток, все это организуете - и придет время включить рубильник. Вот, мы сейчас эту ситуацию видим, когда от простого решения переходят к более сложному.
Конечно же язык должен развиваться для людей раз в 9 лет запускающих скриптики и ни в коем случае не должен соответствовать современным трендам использования языка.
Тем более как появится новая версия интерпретатора без гила, то все старые в интернете удалят и никак нельзя будет скачать.
Эти проекты куда быстрее превратятся в тыкву из-за изменений/удалений в стандартной библиотеке
Просто их нужно будет запускать старым интерпретатором, и всё
В порядке бреда. Оставить в интерпретаторе GIL по умолчанию. Чтобы не грохнулись мегатонны наработанного кода. Для новых проектов (и только тогда, когда это действительно кому-то будет нужно) предусмотреть в командной строке флаг, переводящий интерпретатор в режим без GIL.
Повторюсь - все это в порядке бреда. Чтобы компетентно на эту тему рассуждать надо быть большим знатоком CPython.
Вот объясните мне, зачем вообще использовать треды? Ладно, если делать что-то простенькое. Но для серьезных вещей всегда можно взять мультипроцессинг. И никаких проблем с GIL/
Процесс может помереть от внешних причин, и это добавляет различного гемора.
Почитайте PEP703, благо на него есть ссылка в статье.
Там в начале как раз приведены примеры, кому и когда мультипроцессинг не удобен.
Multiprocessing, в целом, нужен, дабы добиться параллелизма (которого нельзя добиться, используя Потоки из-за наличия GIL), используя более "дорогую" абстракцию ОС (нежели Поток) - Процесс.
- Порождение нового Процесса дороже, чем порождение нового Потока (особенно в Windows / MacOS, где Процессы spawn'ятся, а не fork'аются как в Linux);
- Переключение контекста между Процессами дороже, чем между Потоками;
- Так как у Процессов нет общей памяти (у каждого свой heap), то, для синхронизации оных нужно использовать всякие multiprocessing.Queue / multiprocessing.SharedMemory, которые автоматически сериализуют/десериализуют передаваемые между процессами объекты - дополнительный оверхэд.
Почему все начали рассуждать о коде в будущих версиях? Кто-то ставит все пакеты глобально? Или забыли, что в одной системе может быть несколько питонов без проблем, а виртуальное окружение создается с флагом, какую версию питона использовать?
Мне кажется, это костыли.
Когда новая версия библиотеки не совместима со старой - это плохо. И как костыль, мы используем virtualenv, чтобы для одной программы у нас был пакет python-package-x==1.0.2, а для другой python-package-x==2.0.8. И иногда 2.0.8 вполне может заменить 1.0.2, а вот иногда - нет. И на всякий случай мы для каждой утилитки все дерево зависимостей копируем.
В результате простая утилитка (текстовый файл же по сути!) может за собой тянуть десятки мегабайт всяких dependencies.
virtualenv - не right way, а костыль, потому что у нас (даже у майнтейнеров самых популярных пакетов) как-то не выходит соблюдать обратную совместимость. Тут не надо путать: использовать костыли, когда у нас нога сломана - да, это right way, но считать, что костыль - это и есть right way, это уже ошибка.
Сейчас еще вроде нет проблемы с интерпретатором. Везде, где есть, скажем, python 3.6, можно без страха поставить 3.11 и все будет норм. Несовместимость есть только с переходом python2 -> python3, но в целом мне нравится, как ее реализовали. Сейчас про python2 просто можно забыть и все.
И в golang такая же херота. Еще на заре развития человечества, когда этот обелиск стоят и обезьяны вокруг него с палками прыгали - изобрели shared libraries, чтобы програмки были маленькими, а все прочее было в .so файлах. Причем если у вас две программы используют одну либу - вам достаточно одного .so на них. Но не смогли справиться со сложностями, и в golang перешли к "новаторскому" решению - а давайте даунгрейднемся до уровня обезьян без палок и обелиска, тупо будем статики компилить!
И вы предалагаете не решать проблему с костылями, а плотнее на них опираться? Зачем нам ноги в неудобных ботинках, ноги - атавизм! костыли же решают!
Мы так доиграемся, что каждая утилитка типа ls, less или vim будет со своим докер-контейнером идти.
alias ls="docker run ls"
тупо будем статики компилить
Это одна из фишек golang, за которую в частности его и выбирают.
Везде, где есть, скажем, python 3.6, можно без страха поставить 3.11 и все будет норм.
Я редко использую python, но сталкивался с тем, что типы переименовывались или переезжали в другой пакет. Точно не помню, но вроде бы это касалось базовых типов, используемых в type hints.
Да, выбирают за простоту - проще упихать тупо все в один бинарь, чем, например, сделать несколько .deb пакетов для разных дебианов-убунт, потом .rpm'ы, потом еще что-то...
Я о том и говорю - где-то у нас (человечества) не получилось просто и легко решить задачу с зависимостями, поэтому вот и требуется этот костыль со статиками. Флаг --static
для gcc существует с каменного века же. Golang не изобрел его. Просто отказался решать сложную задачу управления зависимостями (для которой нет простого-легкого-удобного решения).
Кстати, это мне тоже не очень понятно. Задача о зависимостях ведь достаточно общая, унифицированная. Для пакета X нужны пакеты A, B, C. Для каждого из них - свои зависимости тоже. И если у нас есть пакеты X и Y и оба зависят от А - было бы неплохо иметь только одну копию A.
Но почему у нас на одних системах deb, на других rpm, почему в пайтоне приходится использовать pip/pipx а в JS composer/npm ? Мне кажется, достаточно логичным было бы иметь одну простую систему управления зависимостями, которую можно было бы использовать везде. И даже если для нашего нового языка программирования мы хотим свою такую систему (python-pip) - то чтобы могли бы сделать ее на общем фундаменте.
Это крайний идеализм:
"утилиты станут контейнерами", "виртуальное оружение это костыль".
Все это инструменты, спланировать даже один инструмент на декаду вперед сложно, а вы так хотите к каждому пакету, почти все из которых поддерживаются open source сообществом за спасибо.
Вирт.окружение хорошо, пока не начинаешь использовать несколько больших чужих проектов, которые хотят разных версий модулей.
Например "А" хочет pandas==1.x и protobuf<=4.25,
"Б" хочет pandas>=2.2,
"В" которая падает от protobuf<5.
"2028-2030 годы". Вы оптимист. Мир такой сложный и зыбкий. Столько новых точек напряжённости. Стоит ли загадывать дальше 2025 года?
Проблема в искажении концепции тредов. По умолчанию ничего не должно быть общим в тредах, что в 99% случаях и есть в реальных программах. Если что-то нужно общее, то необходимо шарить этот объект и для него уже должны применяться мютексы при изменении, и это будет очень нечасто
Как мне кажется, действительно если программист одновременно меняет объект в двух потоках без мьютекса, то это что-то не то, и в интерпретаторе можно было бы об этом не заморачиваться.
Но проблема в том, что питону не разрешается падать с segmentation fault из-за ошибки программиста.
Есть средства, которые позволяют не заморачиваться об этом программисту. Например, перл. Пометил переменную как общую между потоками - теперь она особо обрабатывается
В статье не написано, но в питоне 3.13 собранном с выключенным GIL, все объекты занимают больше места, чем в сборке с включённым GIL.
Если включение GIL будет можно сделать в рантайме - видимо, размер уравняют. И в таком случае, он для всех станет больше? Вот это будет провал.
Подскажите, откуда такая инфа? Из proposal понятно, что размер должен несущественно вырасти, т.к. добавляются новые поля под флаги и мьютексы, но это не должен быть критический прирост. Я ещё не смотрел pull request'ы, сколько он составляет?
Я собрал CPython без gil (первый скрин) и с ним (второй скрин), и увидел вот что:
![](https://habrastorage.org/getpro/habr/upload_files/c5a/fe5/256/c5afe5256781ae05d449262a4c26d735.jpg)
![](https://habrastorage.org/getpro/habr/upload_files/13d/3e6/935/13d3e6935416cc1222b26f1c8f511393.jpg)
Думаю вот отсюда Garbage collector design (python.org) (GC for the free-threaded build)
Поясните пожалуйста, почему отказ от поколений gc уменьшит количество stop world? Интуитивно кажется что это не должно никак повлиять, но и даже наоборот, отказ спровоцирует увеличение продолжительности stop world...
Провал. Даже если не провал и это каким-то образом дотянут до реальности, то так будет лишь хуже.
Питон станет ещё медленнее, ещё кривее, ещё сложнее. Никто серьёзный это использовать не станет, будут брать старую версию питона и многопроцесность, просто потому что беря эту версию "питона" они будут получать замедление в десяток раз в каждом потоке. Брать лок на обращение к втейблу / референс каунту 'true'... Ух
GIL в Python: как его будут отключать