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);
}
|