Размер стека по умолчанию для pthreads

Насколько я понимаю, размер стека по умолчанию для pthread в Linux равен 16K. Я получаю странные результаты на своей 64-битной установке Ubuntu.

$ ulimit -s 8192 

Также

 pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &stacksize); printf("Thread stack size = %d bytes \n", stacksize); Prints Thread stack size = 8388608 bytes 

Я уверен, что размер стека, если не «8388608». Что может быть неправильным?

  • Как программно получить GID работающего процесса
  • Пользовательский протокол уровня ссылки в UNIX
  • Генерировать необработанные фреймы Ethernet с предварительно загруженными полезными нагрузками памяти с интервалами <1 мс
  • обработка подстановки команд в рыбах против других оболочек (sh, bash, zsh)
  • x86 Emulator для Linux с подробной отладкой
  • -fPIC Флаг в масштабе всей системы?
  • Объединение текстовых файловых каталогов
  • конвертировать исполняемый файл обратно в исходный код C
  • 2 Solutions collect form web for “Размер стека по умолчанию для pthreads”

     int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); 

    Атрибут stacksize должен определять минимальный размер стека (в байтах), выделенный для стека созданных потоков.

    В вашем примере размер стека установлен в 8388608 байт, что соответствует 8 МБ, как возвращено командой ulimit -s Так что соответствует.

    Из описания pthread_create() :

    В Linux / x86-32 размер стека по умолчанию для нового потока составляет 2 мегабайта . В соответствии с реализацией потоков NPTL, если предел гибкого ресурса RLIMIT_STACK во время запуска программы имеет любое значение, отличное от «неограниченного», тогда он определяет размер стека по умолчанию для новых потоков. Используя pthread_attr_setstacksize (3), атрибут размера стека может быть явно установлен в аргументе attr, используемом для создания потока, чтобы получить размер стека, отличный от значения по умолчанию.

    Таким образом, размер стека потоков можно установить либо с помощью установленной функции выше, либо с помощью свойства системы ulimit . Для 16k, о которых вы говорите, неясно, на какой платформе вы это видели и / или если для этого был установлен системный лимит.

    См. Страницу pthread_create и здесь для некоторых интересных примеров.

    Фактически размер виртуального стека составляет 8388608 байт (8 МБ). Конечно, естественно заключить, что это не может быть прав, потому что это смехотворно большой объем памяти для каждого потока, потребляемого для его стека, когда в 99% случаев пара KB, вероятно, все, что им нужно.

    Хорошей новостью является то, что ваш поток использует только объем физической памяти, который ему действительно нужен. Это одна из магических возможностей, которые ваша ОС получает от использования аппаратного модуля управления памятью (MMU) в вашем процессоре. Вот что происходит:

    1. ОС выделяет 8 МБ виртуальной памяти для вашего стека, настраивая таблицы страниц MMU для вашего потока. Это требует очень небольшой ОЗУ для хранения только записей в таблице страниц.

    2. Когда ваш поток работает и пытается получить доступ к виртуальному адресу в стеке, который еще не имеет назначенной ему физической страницы, аппаратное исключение, называемое «ошибка страницы», запускается MMU.

    3. Ядро центрального процессора реагирует на исключение сбоя страницы, переключаясь в режим привилегированного выполнения (у которого есть собственный стек) и вызывает функцию обработчика ошибок сбоя страницы внутри ядра.

    4. Ядро выделяет страницу физической памяти на эту страницу виртуальной памяти и возвращает ее обратно в поток пользовательского пространства.

    Поток пользовательского пространства не видит ничего такого. С его точки зрения, он просто использует стек, как если бы память была там все время. Между тем, стек автоматически растет (или не работает) для удовлетворения потребностей потока.

    MMU является ключевой частью аппаратного обеспечения современных компьютерных систем. В частности, он несет ответственность за много «магии» в системе, поэтому я настоятельно рекомендую узнать больше о том, что делает MMU, и о виртуальной памяти в целом. Кроме того, если ваше приложение чувствительно к производительности и имеет большой объем данных, вы должны понимать, как работает TLB (кэш таблицы страниц MMU), и как вы можете реструктурировать свои данные или ваши алгоритмы, чтобы максимизировать скорость вашего TLB.

    Linux и Unix - лучшая ОС в мире.