Какой размер стека потока по умолчанию в Linux?

Ответ

По умолчанию в большинстве дистрибутивов Linux размер стека основного потока процесса составляет 8 МБ. Это значение можно проверить и изменить.

Практическая проверка:

  1. Командой в терминале: ulimit -s (покажет размер в килобайтах).
  2. Программно на C++:
#include <iostream>
#include <sys/resource.h>

int main() {
    rlimit limit;
    if (getrlimit(RLIMIT_STACK, &limit) == 0) {
        std::cout << "Soft stack limit: " << limit.rlim_cur / 1024 / 1024 << " MBn";
        std::cout << "Hard stack limit: " << limit.rlim_max / 1024 / 1024 << " MBn";
    }
    return 0;
}

Важные нюансы из опыта:

  • Для потоков, создаваемых std::thread или pthread_create, размер стека по умолчанию обычно берётся из атрибутов потока и может отличаться (часто 2-8 МБ). Его можно задать явно.
  • При работе с рекурсивными алгоритмами или большими локальными массивами (int buffer[100000]) легко получить переполнение стека. В таких случаях я либо выделяю память в куче (через std::vector), либо увеличиваю лимит с помощью pthread_attr_setstacksize.
  • В embedded-системах этот лимит часто значительно меньше (порядка десятков или сотен килобайт).

Ответ 18+ 🔞

Да ты посмотри, какая тема поднимается! Прямо как будто вскрываешь капот у старой жигули — вроде всё просто, а на самом деле там овердохуища нюансов. Ну, про стек потока.

Так вот, по умолчанию в линуксе, этот самый стек у главного потока — те самые жирные 8 мегабайт. Не больше, не меньше. Проверить — раз плюнуть. Тыкаешь в терминал ulimit -s и он тебе цифру в килобайтах плюнет. Дели на 1024 — получай свои мегабайты, ёпта.

А если хочешь по-программистки, на плюсах, вот тебе код, бери, не благодари:

#include <iostream>
#include <sys/resource.h>

int main() {
    rlimit limit;
    if (getrlimit(RLIMIT_STACK, &limit) == 0) {
        std::cout << "Soft stack limit: " << limit.rlim_cur / 1024 / 1024 << " MBn";
        std::cout << "Hard stack limit: " << limit.rlim_max / 1024 / 1024 << " MBn";
    }
    return 0;
}

Запустишь — и всё, как на духу, система признается, сколько тебе отсыпала.

А теперь, чувак, самое интересное начинается. Это ж только для главного потока! А как только ты начинаешь плодить потоки через std::thread или эти pthread_create — тут начинается ёперный театр. Размер стека у них может быть другим, часто поменьше, те же 2-4 мегабайта. Но его можно задать руками, если очень хочется, через pthread_attr_setstacksize.

И вот тут главная засада прячется, ядрёна вошь! Начинаешь ты писать рекурсивный алгоритм, который вглубь уходит, или объявляешь в функции массив int arr[100500] — и всё, приехали. Переполнение стека, segmentation fault, и программа накрылась медным тазом. Терпения ноль ебать, когда такое в дебаге ловишь.

Что делать? Да похуй на стек в таких случаях! Берёшь и выделяешь память в куче, через new или, что правильнее, через std::vector. И спи спокойно. Ну или, если уж совсем приперло, увеличиваешь этот самый лимит, как я уже сказал.

И да, запомни ещё одну вещь. Всякие эти встроенные системы, embedded там — это отдельная песня. Там может быть не 8 мегабайт, а жалкие 64 килобайты, и на них ещё ядро и приложение должны ужиться. Так что там с локальными массивами размером с пол-МБ — это прям билет в один конец, в пизду. Там каждая переменная на счету.