You are here:

C++/Thread mutex question

Advertisement


Question
QUESTION: Dear vijayan,
I know this question is not related to your field but I figured you may be able to help me on this still.
Using synchronization with mutexes, I need to come up with a program that solves the traffic light problem. If there is a car passing it should lock the mutex and unlock it when it's passed. If the light is red and there is no car passing it should remain red otherwise it should turn green after a minimum number of seconds.
I tried searching on line for some tutorials on threads and mutex but couldn't find anything that helpful.
You are truly my favorite export on this website so that is why I am writing to you.
I thank you for your help or advice in advance.

ANSWER: the current c++ standard (c++98) has no library support for threads; you have to rely on threading support provided by the native platform. each OS provides its own set of libraries for handling multiple threads. the resulting code is not only non-standard, but also non-portable.

however, there is good news: standard C++ threads are imminent in c++09. these are adapted from the portable thread support provided by the boost libraries.
http://www.boost.org/
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html

see these tutorials on using boost threads:
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
http://paulbridger.net/mutexes

here is a trivial program to illustrate the use of boost threads and mutexes  

//************************************************************
//
// link with the boost thread library
// eg. with gcc on freebsd:
// g++ -Wall -std=c++98 -pedantic -Werror -lboost_thread -I /usr/local/include -L /usr/local/lib sync.cc
//
//************************************************************

#include <boost/thread.hpp>
#include <unistd.h> // sleep (posix)
#include <ctime>
#include <cstdlib>
#include <iostream>

// traffic light state
enum colour { GREEN, RED } ;
colour light_colour = GREEN ;

// mutex to synchronize access to traffic light
boost::mutex traffic_light_mutex ;

// thread to turn red light on/off
void light_timer_thread()
{
 enum { GREEN_TIME = 5, RED_TIME = 2, NUM_SWITCHES = 1024*1024 } ;
 for( int i = 0 ; i < NUM_SWITCHES ; ++i )
 {
     // turn light to red
     {
         // get exclusive ownership of mutex (wait for car to pass)
         boost::mutex::scoped_lock lock_it( traffic_light_mutex ) ;
         // ok, now we have exclusive access to the light

         std::cout << "red..." << std::flush ;
         light_colour = RED ; // set light to red
         sleep( RED_TIME ) ; // wait for RED_TIME seconds
         std::cout << "green" << std::endl ;

         // destructor for lock_it will release the mutex
     }

     light_colour = GREEN ; // set light to green
     sleep( GREEN_TIME ) ; // wait for GREEN_TIME seconds
 }
}

void a_car_passing_thread() // manage passing of a car
{
   enum { CAR_PASS_TIME = 1 } ;

   // get exclusive ownership of mutex (wait for light to tuen green)
   boost::mutex::scoped_lock lock_it( traffic_light_mutex ) ;
   // ok, now we have exclusive access to the light

   std::cout << "passing car..." << std::flush ;
   sleep( CAR_PASS_TIME ) ; // wait for CAR_PASS_TIME seconds
   std::cout << "passed" << std::endl ;

   // destructor for lock_it will release the mutex
}

int main()
{
   std::srand( unsigned( std::time(0) ) ) ;

   // create a timer thread - turn light green->red->green
   boost::thread timer_thread( &light_timer_thread ) ;

   enum { MAX_CAR_ARRIVE_TIME = 5, NUM_CARS = 1024 } ;
   // simulate passing of cars every 0 - MAX_CAR_ARRIVE_TIME secs
   for( int i = 0 ; i < NUM_CARS ; ++i )
   {
       sleep( std::rand() % MAX_CAR_ARRIVE_TIME ) ; // wait for a car to arrive
       boost::thread car_thread( &a_car_passing_thread ) ; // let the car pass
   }

   timer_thread.join() ; // wait for timer_thread to finish
}


if you want to program using the native os thread support, here are a few links.

posix threads tutorials:
https://computing.llnl.gov/tutorials/pthreads/
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

windows threads tutorial:
http://faq.programmerworld.net/programming/win32-multithreading-and-synchronizat





---------- FOLLOW-UP ----------

QUESTION: thanks for your quick reply as usual.
I forgot to mention that this I needed help with C language on this issue and not c++ and that's why I said it was not related.
In terms of OS, I need to run it on linux.
Your suggestion or help would be MUCH appreciated.
thank you so much again.

ANSWER: ok. read these pthread tutorials first.

https://computing.llnl.gov/tutorials/pthreads/
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

and then see if you can understand what this program does. it is an almost verbatim translation of the earlier program (with posix threads and C instead of boost threads and C++).

/************************************************************
*
* link with the pthread library
* eg. with gcc
* gcc -Wall -std=c89 -pedantic -Werror -lpthread use_pthread.c
*
*************************************************************/

#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

enum colour { GREEN, RED } ; /* traffic light state */

int light_colour = GREEN ;

/* mutex to synchronize access to traffic light */
pthread_mutex_t traffic_light_mutex = PTHREAD_MUTEX_INITIALIZER ;

/* thread to turn red light on/off */
void* light_timer_thread( void* arg )
{
 enum { GREEN_TIME = 5, RED_TIME = 2, NUM_SWITCHES = 1024*1024 } ;
 int i ;
 for( i = 0 ; i < NUM_SWITCHES ; ++i )
 {
     /* turn light to red */
     {
         /* get exclusive ownership of mutex (wait for car to pass) */
         pthread_mutex_lock( &traffic_light_mutex ) ;
         /* ok, now we have exclusive access to the light */

         printf( "red..." ) ;
         fflush( stdout ) ;
         light_colour = RED ; /* set light to red */
         sleep( RED_TIME ) ; /* wait for RED_TIME seconds */
         puts( "green" ) ;
         fflush( stdout ) ;

         /* release the mutex */
         pthread_mutex_unlock( &traffic_light_mutex ) ;
     }

     light_colour = GREEN ; /* set light to green */
     sleep( GREEN_TIME ) ; /* wait for GREEN_TIME seconds */
 }
 return NULL ;
}

void* a_car_passing_thread( void* arg ) /* manage passing of a car */
{
   enum { CAR_PASS_TIME = 1 } ;

   /* get exclusive ownership of mutex (wait for light to tuen green) */
   pthread_mutex_lock( &traffic_light_mutex ) ;
   /* ok, now we have exclusive access to the light */

   printf( "passing car..." ) ;
   fflush( stdout ) ;
   sleep( CAR_PASS_TIME ) ; /* wait for CAR_PASS_TIME seconds */
   puts( "passed" ) ;
   fflush( stdout ) ;

   /* release the mutex */
   pthread_mutex_unlock( &traffic_light_mutex ) ;

   return NULL ;
}

int main()
{
     pthread_t timer_thread ;
     int i ;
     enum { MAX_CAR_ARRIVE_TIME = 5, NUM_CARS = 1024 } ;

     srand( (unsigned)time( NULL ) ) ;

     /* create a timer thread - turn light green->red->green */
     pthread_create( &timer_thread, NULL, &light_timer_thread, NULL ) ;

     /* simulate passing of cars every 0 - MAX_CAR_ARRIVE_TIME secs */
     for( i = 0 ; i < NUM_CARS ; ++i )
     {
         pthread_t car_thread ;
         sleep( rand() % MAX_CAR_ARRIVE_TIME ) ; /* wait for a car to arrive */
         pthread_create( &car_thread, NULL, &a_car_passing_thread, NULL ) ;
     }

     pthread_join( timer_thread, NULL ) ; /* wait for timer_thread to finish */
     return 0 ;
}






---------- FOLLOW-UP ----------

QUESTION: Dear vijayan,

thank you SO MUCH for your reply.  I am getting the following error messages when trying to compile and execute
it.  could you tell me what could the problem be please?
thank you in advance.


naji@naji-laptop:~/Documents/Linux_Shit/Mutex$ gcc -Wall -std=c89 -pedantic -Werror -lpthread mutex.c
naji@naji-laptop:~/Documents/Linux_Shit/Mutex$ gcc -o mutex mutex.c
/tmp/ccuzrCvJ.o: In function `main':
mutex.c:(.text+0x145): undefined reference to `pthread_create'
mutex.c:(.text+0x1ad): undefined reference to `pthread_create'
mutex.c:(.text+0x1cd): undefined reference to `pthread_join'
collect2: ld returned 1 exit status


Answer
glad you could solve this yourself by realizing that you need to link with libpthread.

ideally, you should also be calling pthread_mutex_destroy to free the mutex object once it is no longer needed. in this toy program, we are returning from main immediately (which does an orderly termination of the process) and all system resources held by the process are released automatically.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.