CE 155 - pthread Example (Home)

This program is a simple demonstration of some of the functions available in the Linux POSIX threads library. The pthread_create(), pthread_join(), and pthread_exit() functions are used in this program.

int pthread_create(pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg);

The pthread_create function is used to create new threads. It accepts a thread variable, a thread attribute, a start routine function, and an optional argument. To use default thread attributes, pass NULL as the second argument.

After the thread has been succesfully created, it starts execution at the indicated start routine function. What is passed to the function is not the function name, but the address of the function type casted as a void pointer.

Arguments can be passed to the thread using the fourth parameter to pthread_create. Again, a void pointer to the argument is passed. This void pointer should later be type casted back to its true type within the thread routine.

int pthread_join(pthread_t th, void **thread_return);

The pthread_join function is used to wait for termination of a thread --- or wait for the thread to re-join the main thread. In this program, this function is used to ensure that the threads are able to do their work, before the main thread will exit.

Once the threads are created, there is no definite way to know how they will be scheduled. No assurance is given about which thread will finish first. So possible race conditions must be taken into consideration.

You can play around with this program by inserting sleep calls at different points of the code and by removing the pthread_join calls.

To compile and link the program:

gcc -o thread-ex thread-ex.c -Wall -Werror -lpthread

thread-ex.c (download)


/* Includes */
#include <unistd.h>     /* Symbolic Constants */
#include <sys/types.h>  /* Primitive System Data Types */ 
#include <errno.h>      /* Errors */
#include <stdio.h>      /* Input/Output */
#include <stdlib.h>     /* General Utilities */
#include <pthread.h>    /* POSIX Threads */
#include <string.h>     /* String handling */

/* prototype for thread routine */
void print_message_function ( void *ptr );

/* struct to hold data to be passed to a thread
   this shows how multiple data items can be passed to a thread */
typedef struct str_thdata
{
    int thread_no;
    char message[100];
} thdata;

int main()
{
    pthread_t thread1, thread2;  /* thread variables */
    thdata data1, data2;         /* structs to be passed to threads */
    
    /* initialize data to pass to thread 1 */
    data1.thread_no = 1;
    strcpy(data1.message, "Hello!");

    /* initialize data to pass to thread 2 */
    data2.thread_no = 2;
    strcpy(data2.message, "Hi!");
    
    /* create threads 1 and 2 */    
    pthread_create (&thread1, NULL, (void *) &print_message_function, (void *) &data1);
    pthread_create (&thread2, NULL, (void *) &print_message_function, (void *) &data2);

    /* Main block now waits for both threads to terminate, before it exits
       If main block exits, both threads exit, even if the threads have not
       finished their work */ 
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
              
    /* exit */  
    exit(0);
} /* main() */

/**
 * print_message_function is used as the start routine for the threads used
 * it accepts a void pointer 
**/
void print_message_function ( void *ptr )
{
    thdata *data;            
    data = (thdata *) ptr;  /* type cast to a pointer to thdata */
    
    /* do the work */
    printf("Thread %d says %s \n", data->thread_no, data->message);
    
    pthread_exit(0); /* exit */
} /* print_message_function ( void *ptr ) */

Links