#include <stdio.h> #include < String .h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> #define ONE_SECOND 1000000 #define the RANGE 10 #define the PERIOD 2 #define NUM_THREADS . 4 typedef struct { int * the carpark; // an array to simulate parking place int capacity; // vehicle parking capacity int OCCUPIED; // current number of vehicle parking int nextin; // next incoming the position of the vehicle (represented by an array subscript carpark represented) int nextout; // parking position removed next car int cars_in; // sum of the vehicle into the parking lot recorded int cars_out; // record out of the vehicle away from the parking sum pthread_mutex_t Lock ; // mutex to protect the thread data structure to be mutually exclusive manner using pthread_cond_t Space; // condition variables described parking position if available pthread_cond_t cAR; // condition variable describes whether a car parking pthread_barrier_t bar; // thread barrier } cp_t; static void initialise (CP cp_t *, int size) { CP -> OCCUPIED = CP-> nextin = CP-> nextout = CP-> cars_in = CP-> = cars_out0 ; CP -> Capacity = size; CP -> the carpark = ( int *) the malloc (CP-> Capacity * the sizeof (* CP-> the carpark)); // initialize the thread barrier, NUM_THREADS NUM_THREADS = 4 indicates waiting threads synchronization performing pthread_barrier_init (& CP-> bar, NULL, NUM_THREADS); IF (CP-> the carpark == NULL) { perror ( " the malloc () " ); Exit ( . 1 ); } srand ((unsigned int ) getpid ()); the pthread_mutex_init ( & CP-> Lock , NULL); // initialize the parking lock pthread_cond_init (& CP-> Space, NULL); // condition variables described initialization whether parking gapped pthread_cond_init (& CP-> CAR, NULL); // Initialization Description whether a car parking conditions variable } static void * car_in_handler ( void * carpark_in) { cp_t * TEMP; unsigned int SEED; TEMP = (cp_t * ) carpark_in; // pthread_barrier_wait function of said thread has completed the work, until the other thread came pthread_barrier_wait (& temp-> bar ); the while ( . 1 ) { // the thread suspension period, the arrival of the simulated vehicle randomness usleep (rand_r (& the SEED)% ONE_SECOND); pthread_mutex_lock ( & temp-> Lock ); // loop waiting to know there are parking the while (temp-> OCCUPIED == temp-> Capacity) pthread_cond_wait ( & temp-> Space, & temp-> Lock ); // inserted into a vehicle, with a random number identification temp-> the carpark [temp-> nextin] = rand_r (& SEED)% the RANGE; TEMP -> OCCUPIED ++ ; TEMP -> nextin ++ ; TEMP -> nextin% = temp-> Capacity; the TEMP -> cars_in ++ ; // may be desirable to some people waiting for the bus, sending temp-> car condition variable pthread_cond_signal(&temp->car); pthread_mutex_unlock(&temp->lock); } return ((void*)NULL); } static void* car_out_handler(void *carpark_out) { cp_t *temp; unsigned int seed; temp = (cp_t *)carpark_out; pthread_barrier_wait(&temp->bar); for(;;) { usleep(rand_r(&seed) % ONE_SECOND); the pthread_mutex_lock ( & temp-> Lock ); / * obtained after lock access temp-> occupied variable number of time if the vehicle is 0 (OCCUPIED == 0) The pthread_cond_wait operation performed is busy, etc., the lock is released (& temp-> lock) for other routes using known temp-> conditions change again when the car lock with * / the while (temp-> OCCUPIED == 0 ) { the pthread_cond_wait ( & temp-> car, & temp-> lock ); } TEMP -> occupied-- ; TEMP -> nextout ++ ; TEMP -> nextout% = temp-> Capacity; TEMP -> cars_out ++ ; pthread_cond_signal(&temp->space); pthread_mutex_unlock(&temp->lock); } return ((void *)NULL); } static void *monitor(void *carpark_in) { cp_t *temp; temp = (cp_t *)carpark_in; for(;;) { sleep(PERIOD); pthread_mutex_lock(&temp->lock); printf("Delta:%d\n",temp->cars_in - temp->cars_out - temp->occupied); printf("Number of cars in carpark:%d\n",temp->occupied); pthread_mutex_unlock(&temp->lock); } return ((void *)NULL); } int main(int argc,char **argv) { printf("main version 1.0\n"); if(argc != 2) { printf("Usage :%s carparksize\n",argv[0]); exit(. 1 ); } cp_t outpark; initialise ( & outpark, atoi (the argv [ . 1 ])); // initialize data structures parking pthread_t car_in, car_out, m; // defined thread variable pthread_t car_in2, car_out2; / * ** Create to the parking lot parking thread (creator 1) to create a thread pick up the car (consumer 1) from the parking lot to create a thread to the car park (creator 2) create a thread pick up the car from the parking lot (consumer 2) create the conditions for monitoring parking lot thread ** * / pthread_create ( & car_in, NULL, car_in_handler, ( void *) & outpark); pthread_create ( & car_out, NULL, car_out_handler, ( void *) & outpark); pthread_create (& car_in2, NULL, car_in_handler, ( void *) & outpark); pthread_create ( & car_out2, NULL, car_out_handler, ( void *) & outpark); pthread_create ( & m, NULL, Monitor, ( void *) & outpark); // pthread_join of the second parameter is NULL, return the thread represents a do not care state, only the thread terminates the specified waiting pthread_join (car_in, NULL); pthread_join (car_out, NULL); pthread_join (car_in2, NULL); pthread_join (car_out2, NULL); pthread_join ( m, NULL); return 0 ; }