CSCE 313 Lecture 8
« previous | Thursday, February 9, 2012 | next »
POSIX Threads
(Ch. 12)
Why Threads?
Simple interactive game:
while (true) {
/* read keyboard */
/* AND mouse */
/* compute player position */
/* update display */
/* AND other outputs */
/* AND emit sounds */
}
The more things the game has to do, the more complex (and slower) the game becomes.
If one step is blocked, then the entire game stops.
Forking processes won't work since each process would need access to the game variables. Therefore, use threads with shared memory.
if (error = pthread_create(&tid, NULL, read_mouse, NULL)) {
// error: failed to create thread
}
Thread Functions
- pthread_create(pthead_t *restrict thread, const pthread_attr_t * restrict attr, void *(*start_routine)(void *), void *restrict arg) (create a new thread)
- pthread_self (what is my id?)
- pthread_equal (are two thread ids equal?
- pthread_detach (have thread release resources)
- pthread_join (wait for a thread)
- pthread_cancel (terminate another thread)
- pthread_exit (exit the current thread)
- pthread_kill (send a signal to a thread)
Most functions return 0 on success or nonzero error code if unsuccessful
Thread Attributes
Attribute objects
- pthread_attr_destroy
- pthread_attr_init
State
- pthread_attr_getdetachstate
- pthread_attr_setdetachstate
Stack
- pthread_attr_getguardsize
- pthread_attr_setguardsize
- pthread_attr_getstack
- pthread_attr_setstack
Scheduling
- pthread_attr_getinheritedsched
- pthread_attr_setinheritedsched
- pthread_attr_getschedparam
- pthread_attr_setschedparam
- pthread_attr_getschedpolicy
- pthread_attr_setschedpolicy
- pthread_attr_getscope
- pthread_attr_setscope
Thread Safety
A function is thread-safe if multiple threads can execute simultaneous active invocations of the function without interference. Interference typically occurs when threads attempt to access the same shared data.
Some non-thread-safe functions can have a thread-safe version designated with a _r suffix. (e.g. strerror → strerror_r
Sample Code
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#define NUMTHREADS 10
static void *printarg(void *arg) {
fprintf(stderr, "Thread received %d\n", *(int *)arg);
return NULL;
}
int main (void) {
int error, i, j;
pthread_t tid[NUMTHREADS];
for (i=0; i<NUMTHREADS; i++)
// problem: we're passing a pointer, so i will likely be ++'ed by the time it's used
if (error = pthread_create(tid+i, NULL, printarg, (void *)&i)) {
fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
tid[i] = pthread_self();
}
for (j=0; j<NUMTHREADS; j++) {
if (pthread_equal(pthread_self(), tid[j]))
continue;
if (error = pthread_join(tid[j], NULL))
fprintf(stderr, "Failed to join thread: %s\n", strerror(error));
}
printf("All threads done\n");
return 0;
}