Back to TILs

POSIX pthread conditional

Date: 2023-11-01Last modified: 2023-12-22

Table of contents

#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutexFuel;
pthread_cond_t  condFuel;
int             fuel = 0;
void *fuel_filling( void *arg )
{
  for( int i = 0; i < 5; i++ ) {
    pthread_mutex_lock( &mutexFuel );
    fuel += 15;
    printf( "Filled fuel... %d\n", fuel );
    pthread_mutex_unlock( &mutexFuel );
    pthread_cond_signal( &condFuel );
    sleep( 1 );
  }
}

This thread starts first and locks the mutexFuel mutex.

void *car( void *arg )
{
  pthread_mutex_lock( &mutexFuel );
  while( fuel < 40 ) {
    printf( "No fuel. Waiting...\n" );
    pthread_cond_wait( &condFuel, &mutexFuel );
    // Equivalent to:
    // pthread_mutex_unlock(&mutexFuel);
    // wait for signal on condFuel
    // pthread_mutex_lock(&mutexFuel);
  }
  fuel -= 40;
  printf( "Got fuel. Now left: %d\n", fuel );
  pthread_mutex_unlock( &mutexFuel );
}
int main( int argc, char *argv[] )
{
  pthread_t th[2];
  pthread_mutex_init( &mutexFuel, NULL );
  pthread_cond_init( &condFuel, NULL );
  for( int i = 0; i < 2; i++ ) {
    if( i == 1 ) {
      if( pthread_create( &th[i], NULL, &fuel_filling, NULL ) != 0 ) {
        perror( "Failed to create thread" );
      }
    }
    else {
      if( pthread_create( &th[i], NULL, &car, NULL ) != 0 ) {
        perror( "Failed to create thread" );
      }
    }
  }

  for( int i = 0; i < 2; i++ ) {
    if( pthread_join( th[i], NULL ) != 0 ) {
      perror( "Failed to join thread" );
    }
  }
  pthread_mutex_destroy( &mutexFuel );
  pthread_cond_destroy( &condFuel );
  return 0;
}

Possible output

Filled fuel... 15
No fuel. Waiting...
Filled fuel... 30
No fuel. Waiting...
Filled fuel... 45
Got fuel. Now left: 5
Filled fuel... 20
Filled fuel... 35

References