CITS2002 Systems Programming  
prev
CITS2002 CITS2002 schedule  

Stack management of POSIX threads

The POSIX thread standard does not define the size of each thread's stack. Different operating systems will determine the default size (execute  ulimit -a).

A process's stack is used to receive parameters, to provide space for local variables, and store stack frames when other functions are called. Choosing the appropriate stack size for each thread can be very important - too small and code execution will accidentally overwrite another thread's storage, too large and we'll possibly be wasting storage.

If we know ahead of time that a particular thread requires, say, a large per-thread stack - perhaps because it has many or large local variables, or will need to make many 'deep' function calls - then we should not rely on the default stack size, but should specify the required size at time of thread creation.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define  NUM_INT_RESULTS       100000

void *worker(void *threadarg)
{
    int  results[NUM_INT_RESULTS];

    ....
    pthread_exit((void*) threadarg);
}

int main(int argc, char *argv[])
{
    ....
    pthread_attr_t attr;
    size_t         stacksize;

//  Initialize and set thread detached attribute
    pthread_attr_init(&attr);

    pthread_attr_getstacksize(&attr, &stacksize);
    printf("default stack size = %li\n", (long)stacksize);

    stacksize += NUM_INT_RESULTS * sizeof(int);
    printf("stack size needed for worker thread = %li\n", stacksize);  
    pthread_attr_setstacksize(&attr, stacksize);

    err = pthread_create(&thread[tid], &attr, worker, (void *)tid);  
    ....
}

It is notable that we have this fine-grained control when creating individual functions as threads, but not when fork()ing new processes.

 


CITS2002 Systems Programming, Lecture 20, p10, 9th October 2023.