CSCE 313 Lecture 8

From Notes
Jump to navigation Jump to search

« 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. strerrorstrerror_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;
}