Comments 29
Огонь статья, как всегда все очень подробно и интересно расписано! Будет еще интересно посмотреть на то, как поменяется инструментарий для веба на питоне в свете субинтерпретаторов
Отличная статья! Спасибо за упоминание)
Уважаемо, спасибо)
Все написано доступным языком, спасибо!
Как? Уже добавили что ли? Мне казалось то что возится с этим PEP'ом будут ещё долго...
asyncio потребовал от нас переписать весь питон, получить проблему цвета функций, но не решил фундаментальных проблем
Django Framework до сих пор переписывают:
3.0 начали внедрять Async
3.1 асинхронные представления
4.1 асинхронный ORM
4.2 асинхронные формы
5.0 полностью асинхронные middleware
5.1 асинхронные движки сессий с разноцветными модулями: get() - aget(), keys - akeys(), ... декоратор login_required может оборачивать асинхронные представления, асинхронные тесты (AsyncRequestFactory, AsyncClient)
И всё это в добавок к поддержке и развитию старых добрых синхронных ORM, Middleware, View, шаблонов и так далее. Мейнтейнеры пять раз всё прокляли наверное.
Воистину проще было бы с нуля написать асинхронный aDjango, да наверное и aPython (заодно и нумерацию сбросить :)
асинхронные операции с файлами и aopen
так и не добавили в сам питон. понятно почему, но все равно забавно.
А почему собственно? Как с attrs почему бы не сделать что то типа aiofiles стандартом?
ценности в том, чтобы затаскивать что-то в stdlib - не очень много. туда стоит затаскивать только штуки, которые точно не будут меняться. мы надеемся, что файловые системы когда-то смогу стать асинхронными. так что тащить в stdlib хак - не самое лучшее решение; пусть будет отдельным пакетом
Лучше действительно такие новаторские эксперименты проводить, используя стандартные библиотеки и файловые системы как более низкоуровневый элемент или находящиеся в соседней песочнице и имитирующие то что нужно. Поэтому различные хранилища BLOB, базы данных и прочие облака фактически уже превратили всё в asyncio, вопрос только почему нет стандарта уровня posix/iso/ieee итд, пока что это не вышло за корпоративные рамки, хотя уже прошло достаточно времени.
Как сабинтерпретаторы дружат с системными ресурсами, например дескрипторами файлов или мтютексами? Они утекают в сабинтрепретатор по аналогии с тредами и fork или есть магия, которая это предотвращает?
Простите, я не понял вопрос. Мы же в рамках одного процесса работаем. Файловый дескриптор - просто int
, его можно шарить между субинтерпретаторами легко. Про мьютексы - я не понимаю без примера :)
Простите, я не понял вопрос. Мы же в рамках одного процесса работаем
В примерах из статьи, пул сабинтерпретаторов создается по количеству CPU. Как происходит балансировка задач по процессорам если все это работает в рамках одного процесса?
Файловый дескриптор - просто int, его можно шарить между субинтерпретаторами легко
Задача в обратном - предотвратить утечку. Допустим мы открываем файл, читаем построчно и запускаем воркеры для обработки каждой строки. При этом хочется, чтобы воркеры не могли получить доступ нашему файлу, как это случается когда дескрипторы открытых файлов автоматически наследуются дочерними процессами.
Как происходит балансировка задач по процессорам если все это работает в рамках одного процесса?
каждый субинтерпретатор – отдельный OS тред. их работой управляет шедулер OS.
При этом хочется, чтобы воркеры не могли получить доступ нашему файлу
вы сами отправляете в субинтерпретатор данные. если вы что-то явно не пошарили – оно и не пошарится. не отправите файл – к нему не будет доступа
Какой-то особой магии относительно системных ресурсов сейчас нет. Вы, грубо говоря, можете рассматривать приложение с субинтерпретаторами как обычное многопоточное приложение.
Сенсация! Питон наконец додумался сделать то, что в Perl и Tcl/Tk было десятилетиями! Не прошла и четверть века!
Разобрались: вот что на самом деле такое "интерпретатор".
Тут смешно. "Вот видите функцию. Вот она-то и запускает интерпретатор. Вот, а там состояния интерпретатора. Вот мы и разобрались, что такое интерпретатор 😂" - человек, который не понимал, что такое интерпретатор, так и не поймет.
Баферы
А тут каждый раз режет слух. Слово "буфер" в русском языке появилось задолго до IT.
Если посмотрите интервью с Эриком о появлении субинтерпретаторов, то он как раз и говорит, что идея нескольких интерпретаторов появилась еще в середине 90, и как раз под влиянием Tcl/Tk, но была реализована только в C-API и то кое-как.
А сделать это "продакшен-реди" и доступным из Python - а) было никому не надо, б) не было никого кто это мог бы сделать.
Питон в основном развивается энтузиастами и тот же Эрик начал работать над этой темой чуть ли не 10 лет назад и в свое свободное время. И чтобы это сделать пришлось изменить очень многое из того что там наросло годами.
Поэтому это не вопрос "додумался" (понятно что мы все умнее всех остальных), это вопрос того что кто-то это взял и сделал.
Может вопрос немножко не совсем касается нововведения непосредственно, однако видится какая-то глобальная проблема с thread-safe очередями в Python. Первая конечно же по дефолту это multiprocessing.Queue, столкнувшись с удивительным временем в сотни миллисекунд на передачу пакетов данных в десяток килобайт пришлось искать альтернативы вроде faster-fifo, FMQ, рецепты multiprocessing.manager().Queue() и прочие танцы, но радикально проблему они решить не могли. По всей видимости, это связано с механизмами сериализации объектов Pickle или быть может даже особыми средствами ОС (Linux) которые осуществляют переключение. Есть ли какое-либо мнение на этот счёт и возникают ли подобного рода проблемы с субинтерпретаторами. Может действительно в некоторых случаях тогда применять просто shared memory, тогда это будет настоящая каша из двоичных объектов.
Какие в итоге юзкейсы для субинтерпретаторов? Подходят ли они, например, для обработки веб-сервера (по одному на каждый запрос)? Какое количество в рамках одного процесса считается адекватным числом?
Читается так, как будто пришлось все переписать, а профит точечный, все или хотя бы большинство проблем не полечились
Судя по описанному, архитектурно питон движется в сторону движков JavaScript: общий процесс, но с изначально раздельной памятью для каждого сабинтерпретатора. Поэтому юзкейсы думаю будут аналогичны node.js.
Давно такое в ноде? Что-то не попадалось материалов по теме... Можете ссылочку дать?
Например https://v8.dev/docs/embed#contexts .
Я запустил без особых проблем 10к штук на маке м2. Сколько максимум – я не знаю. Надо замерять отдельно. Почему вы решили, что основные проблемы не пофиксили? Вроде бы я как раз описал, что все проблемы как раз таки пофиксили.
Почему вы решили
Я не решил так, а описал впечатление от прочтения. Дочитал, в конце стало непонятно какая судьба теперь у async/await, у threading, у multiprocessing, когда что использовать и т.д. И в бенчмарках нет однозначного фаворита. Я отчасти поэтому спросил про юзкейсы. Что происходит в идеальном сценарии развития языка и библиотек по задумке авторов субинтерпретаторов?
У async/await возможно будущее вместе с субинтерпретаторами. На видео мы как раз целый блок про такое говорим. В будущем, возможно, получится скейлить asyncio через создание доп субинтерпретаторов. У threading - тоже все хорошо. Free-threading и субинтерпретаторы можно и нужно использовать вместе. О чем тоже есть в видео. У мультипроцессинга, кажется, будут некоторые проблемы. Ведь его юзкейсы полностью покрыты. С точки зрения библиотек – я тоже описал, что можно сделать что-то высокоуровневое, вроде actix в rust, чтобы использовать в прикладных приложениях
PEP-734: Субинтерпретаторы в Python 3.14