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

Ответ

В Windows размер стека по умолчанию зависит от разрядности приложения и настроек компоновщика. Типичные значения:

  • Для 32-битных (x86) исполняемых файлов: 1 МБ.
  • Для 64-битных (x64) исполняемых файлов: 2 МБ.

Как с этим работать в C++ проектах: Размер можно изменить на этапе компоновки. В Visual Studio это делается через свойства проекта: Linker > System > Stack Reserve Size. Или прямо в коде с помощью директивы:

// Установка размера стека в 4 МБ для исполняемого файла
#pragma comment(linker, "/STACK:4194304")

При создании потоков через WinAPI (CreateThread) размер стека задаётся параметром dwStackSize. Для потоков std::thread в MSVC стандартный размер стека также обычно равен 2 МБ для x64, но управлять им напрямую из стандартного C++ нельзя — требуется использовать платформо-специфичные расширения или std::thread с пользовательским атрибутным объектом (что сложно).

Из практики: При разработке высоконагруженных серверов на Windows, где каждый клиентский обработчик работает в отдельном потоке, увеличение лимита стека было критически важным для глубоких цепочек вызовов и работы с большими структурами в стеке фрейма.

Ответ 18+ 🔞

Слушай, история про стек в винде — это вообще отдельный вид искусства, ёпта. Представь себе: ты пишешь код, всё летает, а потом раз — и программа накрылась медным тазом, потому что стек кончился. А почему? А потому что по умолчанию там, блядь, как в коммуналке — всем сестрам по серьгам, и места на всех не хватает.

Вот смотри, как там у них, у этих виндовых, заведено:

  • Если твоя программа — 32-битная (это которая x86), то ей на стек выделяют всего 1 МБ. Овердохуища, да? Особенно если у тебя рекурсия или ты туда целые массивы суёшь.
  • Если уже 64-битная (x64), то там щедрее — целых 2 МБ. Но и это, чувак, часто бывает как хуй с горы — покатился, и всё, приехали.

И что с этим делать, если тесно? Можно жесть как накостылять на этапе линковки. В той же Visual Studio лезешь в свойства проекта: Linker > System > Stack Reserve Size и пишешь там своё число, сколько душе угодно. Или, если ты любитель хардкора, прямо в код воткни директиву:

// Выделяем под стек аж 4 МБ, чтобы не бздеть
#pragma comment(linker, "/STACK:4194304")

А вот с потоками — тут вообще пиздопроебибна история начинается. Если ты создаёшь поток через нативный WinAPI (CreateThread), то там есть параметр dwStackSize — вот туда и пихай свой размер, и волнение ебать сразу меньше станет.

Но если ты юзаешь красивый std::thread из плюсов, то, бля буду, тут тебе прямая дорога в сад. Стандартный C++ не даёт тебе ручками размер стека потока выставить. В MSVC по умолчанию для x64 тоже 2 МБ, но изменить это — та ещё песня. Нужно либо платформенно-специфичные расширения искать, либо с атрибутами std::thread шаманить, что сложно до безобразия.

Из личного опыта, блядь: Когда мы сервера высоконагруженные под Windows пилили, где на каждого клиента — свой поток, то увеличение этого лимита было не прихотью, а вопросом выживания. Без этого глубокие цепочки вызовов или работа с жирными структурами в стеке фрейма просто отправляли всё в пизду с диким треском. Так что, э бошка думай, не экономь на стеке, а то будет вам хиросима и нигерсраки в рантайме.