Creating a Thread With a Specified Priority
You can set the priority attribute before creating the thread. The child thread is created with the new priority that is specified in the sched_param structure (this structure also contains other scheduling information).
It is always a good idea to get the existing parameters, change the priority, create the thread, and then reset the priority.
Example 3-2 shows an example of this.
Example 3-2 Creating a Prioritized Thread
Set Stack Size
pthread_attr_setstacksize(3THR)
pthread_attr_setstacksize(3THR) sets the thread stack size.
The stacksize attribute defines the size of the stack (in bytes) that the system will allocate. The size should not be less than the system-defined minimum stack size. See "About Stacks" for more information.
Prototype: int pthread_attr_setstacksize(pthread_attr_t *tattr, size_t size); |
#include <pthread.h> pthread_attr_t tattr; size_t size; int ret; size = (PTHREAD_STACK_MIN + 0x4000); /* setting a new size */ ret = pthread_attr_setstacksize(&tattr, size); |
In the example above, size contains the number of bytes for the stack that the new thread uses. If size is zero, a default size is used. In most cases, a zero value works best.
PTHREAD_STACK_MIN is the amount of stack space required to start a thread. This does not take into consideration the threads routine requirements that are needed to execute application code.
Return Values
pthread_attr_setstacksize() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.
The value of size is less than PTHREAD_STACK_MIN, or exceeds a system-imposed limit, or tattr is not valid.
Get Stack Size
pthread_attr_getstacksize(3THR)
pthread_attr_getstacksize(3THR) returns the stack size set by pthread_attr_setstacksize().
Prototype: int pthread_attr_getstacksize(pthread_attr_t *tattr, size_t *size); |
#include <pthread.h> pthread_attr_t tattr; size_t size; int ret; /* getting the stack size */ ret = pthread_attr_getstacksize(&tattr, &size); |
Return Values
pthread_attr_getstacksize() returns zero after completing successfully. Any other return value indicates that an error occurred. If the following condition occurs, the function fails and returns the corresponding value.
EINVAL
tattr is not valid.
About Stacks
Typically, thread stacks begin on page boundaries and any specified size is rounded up to the next page boundary. A page with no access permission is appended to the overflow end of the stack so that most stack overflows result in sending a SIGSEGV signal to the offending thread. Thread stacks allocated by the caller are used as is.
When a stack is specified, the thread should also be created PTHREAD_CREATE_JOINABLE. That stack cannot be freed until the pthread_join(3THR) call for that thread has returned, because the thread's stack cannot be freed until the thread has terminated. The only reliable way to know if such a thread has terminated is through pthread_join(3THR).
Generally, you do not need to allocate stack space for threads. The threads library allocates 1 megabyte (for 32 bit) or 2 megabytes (for 64 bit) of virtual memory for each thread's stack with no swap space reserved. (The library uses the MAP_NORESERVE option of mmap() to make the allocations.)
Each thread stack created by the threads library has a red zone. The library creates the red zone by appending a page to the overflow end of a stack to catch stack overflows. This page is invalid and causes a memory fault if it is accessed. Red zones are appended to all automatically allocated stacks whether the size is specified by the application or the default size is used.
Note - Because runtime stack requirements vary, you should be absolutely certain that the specified stack will satisfy the runtime requirements needed for library calls and dynamic linking.
There are very few occasions when it is appropriate to specify a stack, its size, or both. It is difficult even for an expert to know if the right size was specified. This is because even a program compliant with ABI standards cannot determine its stack size statically. Its size is dependent on the needs of the particular runtime environment in which it executes.
Building Your Own Stack
When you specify the size of a thread stack, be sure to account for the allocations needed by the invoked function and by each function called. The accounting should include calling sequence needs, local variables, and information structures.
Occasionally you want a stack that is a bit different from the default stack. An obvious situation is when the thread needs more than the default stack size. A less obvious situation is when the default stack is too large. You might be creating thousands of threads and not have enough virtual memory to handle the gigabytes of stack space that this many default stacks require.
The limits on the maximum size of a stack are often obvious, but what about the limits on its minimum size? There must be enough stack space to handle all of the stack frames that are pushed onto the stack, along with their local variables, and so on.
You can get the absolute minimum limit on stack size by calling the macro PTHREAD_STACK_MIN, which returns the amount of stack space required for a thread that executes a NULL procedure. Useful threads need more than this, so be very careful when reducing the stack size.
#include <pthread.h> pthread_attr_t tattr; pthread_t tid; int ret; size_t size = PTHREAD_STACK_MIN + 0x4000; /* initialized with default attributes */ ret = pthread_attr_init(&tattr); /* setting the size of the stack also */ ret = pthread_attr_setstacksize(&tattr, size); /* only size specified in tattr*/ ret = pthread_create(&tid, &tattr, start_routine, arg); |