Как мы все знаем, в питоне существуют потоки, однако они выполняются в рамках одного процесса асинхронно: т.е. ты не сможешь в один и тот же момент времени совершить несколько операций с помощью потоков. Всё это благодаря GIL, но тема не об этом. Я задался вопросом: в чем тогда разница между многопоточностью и библиотекой asyncio в питоне, если по факту они оба асинхронны.
Наткнулся на хорошую статью:
A better way for asynchronous programming: asyncio over multi-threading | by Qian (Aria) Li | Towards Data ScienceИз результатов тестов видно, что при малых количествах запросов многопоточность лучше, чем asyncio (~2 раза)
Однако при больших количествах победителем выходит asyncio (~3 раза)
Мой вопрос - почему так? В статье описана лишь расшифровка результатов, но не причина их возникновения.
Почему выигрывает asyncio - я могу понять: система тратит какое-то время на переключение между потоками при многопоточности в то время, как asyncio работает в одном потоке. Но проигрыш asyncio при малых количествах запросов - вызывает вопросы.
Нажмите, чтобы раскрыть...
разница в подходах
asyncio и сходные в других языках концепции это кооперативная многозадачность
корутина в рамках этого протокола останавливается только тогда, когда сама захочет, передавая управление кому-нибудь
то есть у нас все операции помимо await и всяких аналогичных конструкций — живут в критической секции кода
критическая секция эта та, что требует полного исполнения кода
минусы?
мы ответственны за то, как долго у нас исполняется код каждой корутины
не скажешь await нигде, ну она и исполнится до конца, захватив всё время исполнения
зачем нам старая добрая вытесняющая многозадачность?
ну условно у нас есть много разных не особо зависимых друг от друга "потоков кода", которые вычисления на фоне должны по нашей задумке делать и изредка синхронизироваться
и мы не очень хотим париться по поводу того, чтобы это было всё максимально эффективно и имело нормальный отклик
поэтому мы просто создаём потоки и передаём по сути всю головную боль операционной системе
пусть она и её планировщик планирует: сама останавливает и передаёт управление между разными потоками
минусы?
головная боль с обычными потоками начинается, когда они сильно друг от друга зависят, имеют много критических секций
и нам надо организовывать бесконечно сложные танцы с семафорами и прочими механизмами синхронизации
потому что в отличие от корутин исполнение потока может быть прервано в любой момент и мы не можем ничего особо гарантировать, если не позаботились о синхронизациях заранее
короче, учитывая, что (как я понял) event loop умеет работать со всеми: процессам, потокам и корутинами, то ты просто можешь смешивать эти вещи вместе и жить как царь
Если списывать это на погрешность тестов, то тогда немного другой вопрос - нахрена нужна многопоточка в питоне?
Нажмите, чтобы раскрыть...
в общем, отвечая на твой вопрос, для того, чтобы был выбор между разными инструментами, которые не взаимозаменимы