Обычно создание собственного стека предполагает, что он будет немного отличаться от стека по умолчанию. Как правило, задача состоит в выделении более чем одного мегабайта для стека. Иногда стек по умолчанию, наоборот, является слишком большим. Можно создать тысячи потоков, и тогда виртуальной памяти будет недостаточно, чтобы работать с гигабайтами пространств стека при использовании размера по умолчанию.
Абсолютный минимальный предел размера стека можно определить, вызывая
макрос PTHREAD_STACK_MIN (определенный в
<pthread.h>),
который возвращает количество памяти стека, требуемого для потока,
выполняющего пустую процедуру (NULL). Реальные потоки нуждаются
в большем стеке, поэтому нужно очень осторожно сокращать его размер.
Функция pthread_attr_setstacksize() используется для установки размера стека текущего потока.
Атрибут stacksize определяет размер стека в байтах. Этот стек выделяется системой и его размер не должен быть меньше минимального. При успешном завершении функция возвращает 0. Пример вызова:
pthread_attr_t tattr;
int stacksize;
int ret;
/* установка нового размера */
stacksize = (PTHREAD_STACK_MIN + 0x4000);
ret = pthread_attr_setstacksize(&tattr, stacksize);
Функция pthread_attr_getstacksize(pthread_attr_t *tattr, size_t *size) используется для получения размера стека текущего потока:
pthread_attr_t tattr;
int stacksize;
int ret;
/* получение размера стека */
ret = pthread_attr_getstacksize(&tattr, &stacksize);
Иногда возникает потребность установить базовый адрес стека. Для этого используется функция pthread_attr_setstackaddr():
void *stackaddr);
Следующий пример показывает способ создания потока со стеком определенного размера по указанному адресу:
pthread_attr_t tattr;
pthread_t tid;
int ret;
void *stackbase;
int size = PTHREAD_STACK_MIN + 0x4000;
stackbase = (void *) malloc(size);
/* инициализация значениями по умолчанию */
ret = pthread_attr_init(&tattr);
/* установка размера стека */
ret = pthread_attr_setstacksize(&tattr, size);
/* установка базового адреса стека */
ret = pthread_attr_setstackaddr(&tattr, stackbase);
ret = pthread_create(&tid, &tattr, func, arg);