Стопки сопрограмм растут в Lua, Python, Ruby или любых других языках?

Есть некоторые языки, которые поддерживают детерминированный легкий параллелизм - сопрограмму.

  1. Луа - сопрограмма
  2. Python без стека - тасклет
  3. Рубин - волокно
  4. должно быть намного больше... но в настоящее время я не имею особого представления.

Во всяком случае, насколько я знаю, для этого нужно много отдельных стеков, поэтому я хочу знать, как эти языки справляются с ростом стека. Это потому, что я прочитал некоторые упоминания о Ruby Fiber, который поставляется с 4KB - очевидно, большие накладные расходы - и они рекламируют это как функцию, которая предотвращает переполнение стека. Но я не понимаю, почему они просто говорят, что стеки будут расти автоматически. Нет смысла в том, что виртуальная машина - которая не ограничена стеком C - не может справиться с ростом стека, но я не могу это подтвердить, потому что я плохо знаю внутренние компоненты.

Как они справляются с ростом стека на таких микропотоках? Есть ли явные / неявные ограничения? Или просто будет обрабатываться четко и автоматически?

1 ответ

Для рубина:

Согласно этому техническому докладу Google, ruby vm использует слегка хакерскую систему, включающую в себя создание копии стека C для каждого потока, а затем копирование этого стека в основной стек при каждом переключении между волокнами. Это означает, что Ruby по-прежнему ограничивает каждое волокно стеком более 4 КБ, но интерпретатор не переполняется, если вы переключаетесь между глубоко вложенными волокнами.

Для питона:

задачи доступны только в варианте без стека. Каждый поток получает свой собственный стек на основе кучи, так как в стеке Python VM использует стеки на основе кучи. Этот беспорядок они по своей сути ограничены только размером кучи в росте стека. Это означает, что для 32-разрядных систем эффективный предел все еще составляет 1-4 ГБ.

Для Луа:

Lua использует стек, основанный на куче, поэтому он ограничен только размером кучи при наращивании стека. Каждая сопрограмма получает свой собственный стек в памяти. Это означает, что для 32-разрядных систем эффективный предел все еще составляет 1-4 ГБ.

Чтобы добавить еще пару в ваш список, C# и VB.Net теперь поддерживают async/await. Это система, которая позволяет программе предварительно выполнять трудоемкую операцию, а остальная часть этой функции продолжается после этого. Это реализуется путем создания объекта, представляющего метод с помощью одного метода, который вызывается для перехода к следующему шагу в методе, который вызывается при попытке получить результат и различные другие внутренние расположения. Исходный метод заменяется на тот, который создает объект. Это означает, что на глубину рекурсии это не влияет, так как метод никогда не бывает на несколько шагов дальше по стеку, чем вы ожидаете.

Другие вопросы по тегам