Вопрос

Есть много вопросов, связанных с Stackless Python.Но никто не отвечает на этот мой вопрос, я думаю (поправьте меня, если ошибаюсь - пожалуйста!).Об этом все время ходит какая-то шумиха, так что мне любопытно узнать.Для чего бы я использовал Stackless?Чем это лучше CPython?

Да, у него есть зеленые потоки (без стеков), которые позволяют быстро создавать множество облегченных потоков, пока никакие операции не блокируются (что-то вроде потоков Ruby?).Для чего это здорово?Какие еще функции, которые у него есть, я хочу использовать поверх CPython?

Это было полезно?

Решение

Это позволяет вам работать с огромным количеством параллелизма.Никто в здравом уме не стал бы создавать сто тысяч системных потоков, но вы можете сделать это с помощью stackless.

В этой статье мы тестируем, как это делается, создавая сто тысяч тасклетов как на Python, так и на Google Go (новый язык программирования).: http://dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html

Удивительно, но даже если Google Go скомпилирован в машинный код и они рекламируют свою реализацию совместных подпрограмм, Python все равно выигрывает.

Stackless был бы хорош для реализации алгоритма map / reduce, где у вас может быть очень большое количество редукторов в зависимости от ваших входных данных.

Другие советы

Основным преимуществом Stackless Python является поддержка очень легких сопрограмм.CPython изначально не поддерживает сопрограммы (хотя я ожидаю, что кто-нибудь опубликует в комментариях взлом на основе генератора), поэтому Stackless - явное улучшение CPython, когда у вас возникает проблема, связанная с сопрограммами.

Я думаю, что основная область, в которой они преуспевают, - это когда в вашей программе выполняется много параллельных задач.Примерами могут быть игровые объекты, которые запускают сценарий цикла для своего искусственного интеллекта, или веб-сервер, который обслуживает множество клиентов с медленно создаваемыми страницами.

Однако у вас все еще есть много типичных проблем с корректностью параллелизма в отношении совместно используемых данных, но детерминированное переключение задач упрощает написание безопасного кода, поскольку вы точно знаете, куда будет передано управление, и, следовательно, знаете точные точки, в которых общее состояние должно быть актуальным.

Терлер уже упоминал, что stackless использовался в Eve Online.Имейте в виду, что:

(..) stackless добавляет к этому дополнительный поворот, позволяя разделять задачи на более мелкие задачи, тасклеты, которые затем могут быть отделены от основной программы для самостоятельного выполнения.Это можно использовать для задач "запустить и забыть", таких как отправка электронного письма или отправка события, или для операций ввода-вывода, напримеротправка и прием сетевых пакетов.Один тасклет ожидает получения пакета из сети, в то время как другие продолжают выполнять игровой цикл.

В некотором смысле он похож на потоки, но не является упреждающим и явно запланированным, поэтому проблем с синхронизацией меньше.Кроме того, переключение между тасклетами происходит намного быстрее, чем переключение потоков, и у вас может быть огромное количество активных тасклетов, в то время как количество потоков сильно ограничено компьютерным оборудованием.

(получил эту цитату из здесь)

На PyCon 2009 было дано очень интересный разговор, описывающий, почему и как Stackless используется в CCP Games.

Кроме того, есть очень хороший вводный материал, который описывает, почему stackless является хорошим решением для ваших приложений.(возможно, она несколько устарела, но я думаю, что ее стоит прочитать).

EVEOnline в основном запрограммирован на Python без стеков.У них есть несколько блогов разработчиков, посвященных его использованию.Кажется, это очень полезно для высокопроизводительных вычислений.

Хотя я не использовал Stackless сам по себе, я использовал Greenlet для реализации высококонкурентных сетевых приложений.Вот некоторые из вариантов использования Linden Lab, к которым она применима::высокопроизводительные интеллектуальные прокси-серверы, быстрая система для распределения команд по огромному количеству компьютеров и приложение, которое выполняет тонну операций записи и чтения в базу данных (в соотношении примерно 1: 2, что очень трудоемко при записи, поэтому большую часть времени оно тратит на ожидание возврата базы данных), а также устройство типа веб-сканера для обработки внутренних веб-данных.В принципе, любое приложение, которое ожидает, что ему придется выполнять много операций сетевого ввода-вывода, выиграет от возможности создавать баджиллион легких потоков.10 000 подключенных клиентов не кажутся мне такой уж большой суммой.

Однако Stackless или Greenlet на самом деле не являются полным решением.Они очень низкоуровневые, и вам придется немало потрудиться, чтобы создать с их помощью приложение, которое использует их в полной мере.Я знаю это, потому что у меня есть библиотека, которая предоставляет сетевой уровень и уровень планирования поверх Greenlet, в частности, потому, что с ней намного проще писать приложения.Сейчас их там целая куча;Я поддерживаю Eventlet, но также есть Concurrence, Chiral и, возможно, еще несколько, о которых я не знаю.

Если приложение, которое вы хотите написать, похоже на то, о чем я писал, рассмотрите одну из этих библиотек.Выбор Stackless против Greenlet несколько менее важен, чем решение о том, какая библиотека лучше всего соответствует потребностям того, что вы хотите сделать.

Основная полезность зеленых потоков, на мой взгляд, заключается в реализации системы, в которой у вас есть большое количество объектов, выполняющих операции с высокой задержкой.Конкретным примером может быть общение с другими машинами:

def Run():
    # Do stuff
    request_information() # This call might block
    # Proceed doing more stuff

Потоки позволяют вам писать приведенный выше код естественным образом, но если количество объектов достаточно велико, потоки просто не смогут работать адекватно.Но вы можете использовать зеленые нити даже в действительно больших количествах.В request_information() выше можно было бы переключиться на какой-нибудь планировщик, где ждет другая работа, и вернуться позже.Вы получаете все преимущества возможности вызывать "блокирующие" функции как будто они немедленно возвращаются без использования потоков.

Очевидно, что это очень полезно для любого вида распределенных вычислений, если вы хотите писать код простым способом.

Это также интересно для нескольких ядер, чтобы смягчить ожидание блокировок:

def Run():
    # Do some calculations
    green_lock(the_foo)
    # Do some more calculations

В green_lock функция в основном попытается получить блокировку и просто переключится на основной планировщик, если произойдет сбой из-за того, что другие ядра используют объект.

Опять же, зеленые потоки используются для смягчения блокировки, позволяя коду писаться естественным образом и при этом хорошо работать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top