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

Что делает "ulimit -s неограниченное"?

Понятно, что многие связанные вопросы о распределении стека

Что и где находится стек и куча?

Почему существует ограничение на размер стека?

Размер стека и памяти кучи

Однако на разных машинах * nix я могу выполнить команду bash

ulimit -s unlimited

или команда csh

set stacksize unlimited

Как это изменится, как выполняются программы? Имеются ли какие-либо последствия для производительности программы или системы (например, почему это не было бы по умолчанию)?

В случае, когда важны более подробные сведения о системе, я в основном занимаюсь программами, скомпилированными с GCC в Linux, работающими на оборудовании x86_64.

4b9b3361

Ответ 1

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

Для ограничения программ, использующих огромное количество стекового пространства, обычно устанавливается ограничение через ulimit -s. Если мы удалим этот лимит с помощью ulimit -s unlimited, наши программы будут в состоянии поглощать оперативную память для своего постоянно растущего стека до тех пор, пока в конечном итоге система полностью не исчерпает память.

int eat_stack_space(void) { return eat_stack_space(); }
// If we compile this with no optimization and run it, our computer could crash.

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

Влияние на производительность незначительно, но существует. Используя команду time, я обнаружил, что устранение ограничения стека увеличило производительность на несколько долей секунды (по крайней мере, в 64-битной Ubuntu).

Ответ 2

Mea culpa, размер стека может быть неограниченным. _STK_LIM по умолчанию, _STK_LIM_MAX - это то, что отличается для каждой архитектуры, как видно из include/asm-generic/resource.h:

/*
 * RLIMIT_STACK default maximum - some architectures override it:
 */
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX           RLIM_INFINITY
#endif

Как видно из этого примера, общее значение бесконечно, где RLIM_INFINITY опять же в общем случае определяется как:

/*
 * SuS says limits have to be unsigned.
 * Which makes a ton more sense anyway.
 *
 * Some architectures override this (for compatibility reasons):
 */
#ifndef RLIM_INFINITY
# define RLIM_INFINITY          (~0UL)
#endif

Итак, я предполагаю, что реальный ответ - размер стека CAN может быть ограничен некоторой архитектурой, тогда неограниченная трассировка стека будет означать, что _STK_LIM_MAX определяется, а в случае бесконечности - бесконечно. Для получения подробной информации о том, что означает установить ее в бесконечность и какие последствия она может иметь, обратитесь к другому ответу, она лучше, чем моя.

Ответ 3

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

Ответ @seisvelas почти содержит правильный ответ на вопрос. Тем не менее, он похоронен глубоко в множестве ложных утверждений - см. Комментарии. Таким образом, я чувствовал себя обязанным написать этот ответ.