Подтвердить что ты не робот

Для чего я должен использовать Stackless Python?

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

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 в основном попытается получить блокировку и просто переключиться на главный планировщик, если она не удалась из-за других ядер с использованием объекта.

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