Before the POSIX standard, each computer vendor would implement its own thread library and the resulting programs were not protable across different computer systems.
#include <pthread.h> |
cc -mt [other flags] file... -lpthread [other libraries] |
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine, void*), void *arg); |
Input Parameters:
|
Output Parameters:
|
Return value:
|
void *worker(void *arg) { ... computational routine... } pthread_t tid[100]; int main(int argc, char *argv[]) { int i, num_threads; ... for (i = 0; i < num_threads; i = i + 1) { if ( pthread_create(&tid[i], NULL, worker, NULL) != 0 ) { cout << "Cannot create thread " << i << endl; exit(1); } } } |
pthread_attr_t attr; |
pthread_attr_init( &attr ); |
After initialization, you can now set the desired thread property using a number of set thread attribute functions
Attribute | Default | Meaning of default |
---|---|---|
contentionscope | PTHREAD_SCOPE_PROCESS | Thread will compete for resources within the process |
detachstate | PTHREAD_CREATE_JOINABLE | Thread is joinable by other threads |
stackaddr | NULL | Workspace (stack) used by thread is allocated (reserved) by the operating system |
stacksize | NULL | Workspace size used by thread is determined by the operating system |
priority | 0 | Priority of the thread (the lower the higher the priority) |
policy | SCHED_OTHER | The scheduling policy is determined by the system |
inheritsched | PTHREAD_EXPLICIT_SCHED | scheduling policy and parameters are not inherited but explicitly defined by the attribute object |
guardsize | PAGESIZE | size of guard area for a thread's created stack (this area will help determine if the thread has exceeded the total amount of space that was allocated for the thread) |
|
|
int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ); |
Example:
pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 10000000); // 10000000 bytes stack |
set up data (sequential) computation on the data (parallel) gather result and set up new data (sequential) more computation on the data (parallel) ... and so on |
Hence, threads must WAIT on each other.
|
int pthread_join(pthread_t thread, void **status); |
pthread_t TID; int *out; pthread_create(&TID, NULL, my_proc, NULL); ... pthread_join(TID, (void **) &out); cout << "Output value = " << *out ; |
|
Compile: CC -mt thread-join.C
extern "C" void * my_proc(void * input) { .... } |
/* -------------------------------------------------------- Worker thread will receive an INTEGER input parameter -------------------------------------------------------- */ extern "C" void *worker(void * arg) { int * p; p = (int *) arg; // Convert back to the actual type cout << "Hi, my input parameter is " << *p << endl; return(NULL); /* Thread exits (dies) */ } |
Compile with: CC -mt thread04.C
pthread_t TID; /* Thread ID - used for signaling */ pthread_attr_t attr; /* Thread attribute values for creation */ myType param; /* --------------------------------------------------- Clear out thread attributes (use default values) --------------------------------------------------- */ if (pthread_attr_init(&attr) != 0) { perror("Problem: pthread_attr_init"); exit(1); } /* --------------------------------------------------------- Set some thread attributes if needed --------------------------------------------------------- */ if ( pthread_attr_setstacksize(&attr, 10000000) != 0) { perror("Problem: pthread_attr_setstacksize"); exit(1); } initialzie param....; /* -------------------------------------------------------------- Create threads - this function will be called MANY times ! -------------------------------------------------------------- */ if (pthread_create(&TID, &attr, my_proc, ¶m) != 0) { perror("Problem: pthread_create"); exit(1); } /* -------------------------------------------------------------- Commonly used: pthread_create(&TID, NULL, my_proc, NULL) -------------------------------------------------------------- */ /* -------------------------------------------------------------- Wait for threads to complete their tasks... -------------------------------------------------------------- */ pthread_join( TID, (void **) output ); |
We must also provide a function for the thread to execute:
extern "C" void *my_proc((void *) arg) <-- new thread will begin { execution with this function .... myType *p; p = (myType *) arg; .... (do the job).... pthread_exit( (void *) & output ); return(NULL); } |