Для чего мне использовать Stackless Python?
есть много вопросов, связанных с Stackless Python. Но никто не отвечает на этот мой вопрос, я думаю (поправьте меня, если неправильно-пожалуйста!). Там какой-то шум об этом все время, поэтому мне любопытно знать. Для чего мне использовать Stackless? Как это лучше, чем CPython?
Да, у него есть зеленые потоки (stackless), которые позволяют быстро создавать много легких потоков, пока никакие операции не блокируются (что-то вроде потоков Ruby?). Для чего все это? Какие еще функции он имеет I хотите использовать над CPython?
6 ответов
Это позволяет работать с большим количеством параллелизма. Никто в здравом уме не создаст сто тысяч системных потоков, но вы можете сделать это, используя stackless.
в этой статье тесты делают именно это, создавая сто тысяч tasklets в Python и Google Go (новый язык программирования): http://dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html
удивительно, даже если Google Go скомпилирован в собственный код, и они рекламируют реализацию своих подпрограмм, Python все равно выигрывает.
Stackless было бы хорошо для реализации алгоритма map / reduce, где вы можете иметь очень большое количество редукторов в зависимости от ваших входных данных.
Stackless Python и является поддержка очень легкий сопрограммы. CPython не поддерживает coroutines изначально (хотя я ожидаю, что кто-то опубликует взлом на основе генератора в комментариях), поэтому Stackless-это явное улучшение CPython, когда у вас есть проблема, которая выигрывает от coroutines.
Я думаю, что основная область, где они excel, когда у вас есть много параллельных задач, запущенных в вашей программе. Примерами могут быть игровые объекты, которые запускают сценарий цикла для их AI, или веб-сервер, который обслуживает много клиентов со страницами, которые медленно создаются.
У вас все еще есть много типичных проблем с корректностью параллелизма, однако в отношении общих данных, но детерминированное переключение задач упрощает написание безопасного кода, поскольку вы точно знаете, где будет передан контроль, и поэтому знаете точные точки, в которых общее состояние должно быть обновлено.
Thirler уже упоминал, что stackless был использован в Ева онлайн. Имейте в виду, что:
(..) stackless добавляет еще один поворот к этому, позволяя задачам быть разделены на более мелкие задачи, Tasklets, которые затем могут быть отделены от основной программы для выполнения самостоятельно. Это может быть использовано для задач "пожар-и-забыть", таких как отправка электронной почты или отправка события, или для операций ввода-вывода, например, отправка и получение сетевых пакетов. Один tasklet ожидает пакет из сети, в то время как другие продолжают запускать игровой цикл.
Это в некотором роде как потоки, но не является упреждающим и явно запланированным, поэтому меньше проблем с синхронизацией. Кроме того, переключение между наборами задач намного быстрее, чем переключение потоков, и у вас может быть огромное количество активных наборов задач, в то время как количество потоков строго ограничено компьютерным оборудованием.
(получил эту цитату из здесь)
на PyCon 2009 было дано очень интересный разговор, описывая, почему и как Stackless используется в играх CCP.
кроме того, есть очень хорошая вводный материал, который описывает, почему stackless является хорошим решением для ваших приложений. (он может быть несколько старым, но я думаю, что его стоит прочитать).
EVEOnline в основном запрограммирован на Stackless Python. У них есть несколько блогов о его использовании. Кажется, это очень полезно для высокопроизводительных вычислений.
хотя я не использовал сам Stackless, я использовал Greenlet для реализации параллельных сетевых приложений. Некоторые из вариантов использования Linden Lab: высокопроизводительные интеллектуальные прокси, быстрая система распределения команд на огромном количестве машин и приложение, которое делает тонну записей и чтений базы данных (в соотношении около 1: 2, что очень тяжело для записи, поэтому он тратит большую часть своего времени на ожидание возврата базы данных), и web-crawler-Type-вещь для внутренних веб-данных. В основном любое приложение, которое ожидает, что придется делать много сетевых ввода-вывода, выиграет от возможности создания bajillion легких потоков. 10 000 подключенных клиентов не кажутся мне большой проблемой.
Stackless или Greenlet на самом деле не являются полным решением. Они очень низкоуровневые, и вам придется сделать много работы, чтобы создать приложение с ними, которое использует их в полной мере. Я знаю это, потому что Я поддерживаю библиотеку, которая обеспечивает сетевой и плановый слой поверх Greenlet, особенно потому, что писать приложения с ним намного проще. Теперь их много; я поддерживаю Eventlet, но также есть совпадение, Хираль и, вероятно, еще несколько, о которых я не знаю.
Если вид приложения, которое вы хотите написать, звучит как то, о чем я писал, рассмотрим одну из этих библиотек. Выбор Stackless vs Greenlet несколько менее важен, чем решение о том, что библиотека лучше всего соответствует потребностям того, что вы хотите сделать.
основная полезность для зеленых потоков, как я вижу, заключается в реализации системы, в которой у вас есть большое количество объектов, которые выполняют операции с высокой задержкой. Конкретным примером может служить общение с другими машинами:
def Run():
# Do stuff
request_information() # This call might block
# Proceed doing more stuff
Threads позволяют писать приведенный выше код естественно, но если количество объектов достаточно велико, потоки просто не могут работать адекватно. Но вы можете использовать зеленые потоки даже в очень больших количествах. The request_information()
выше могли бы перейти к некоторые планировщик, где другая работа ждет и вернуться позже. Вы получаете все преимущества возможности вызова "блокирующих" функций как будто они возвращаются немедленно без использования потоков.
это, очевидно, очень полезно для любого вида распределенных вычислений, если вы хотите написать код простым способом.
это также интересно для нескольких ядер, чтобы смягчить ожидание блокировки:
def Run():
# Do some calculations
green_lock(the_foo)
# Do some more calculations
на green_lock
функция в основном попытается чтобы получить блокировку и просто переключиться на главный планировщик, если он не работает из-за других ядер, использующих объект.
опять же, зеленые потоки используются для смягчения блокировки, позволяя коду быть написанным естественно и по-прежнему хорошо работать.