// Compile with g++ h20.cc -lpthread // #include #include #include #include using namespace std; #define NUMTHRDS 100 int status; int n = 256; pthread_t thds[NUMTHRDS]; pthread_mutex_t mutex; sem_t sH, sO; int cH = 0, cO = 0; int main ( int argc, char *argv[] ); void *H ( void *arg ); void *O ( void *arg ); int main ( int argc, char *argv[] ) { int i; sem_init( &sH, 0, 0 ); sem_init( &sO, 0, 0 ); pthread_attr_t attr; pthread_mutex_init ( &mutex, NULL ); pthread_attr_init ( &attr ); pthread_attr_setdetachstate ( &attr, PTHREAD_CREATE_JOINABLE ); for ( i = 0; i < NUMTHRDS; i++ ) { if ( 0 == ( rand() % 2 ) ) pthread_create ( &thds[i], &attr, H, ( void * ) i ); else pthread_create ( &thds[i], &attr, O, ( void * ) i ); } pthread_attr_destroy ( &attr ); for ( i = 0; i < NUMTHRDS; i++ ) { pthread_join ( thds[i], ( void ** ) &status ); } pthread_mutex_destroy ( &mutex ); // pthread_exit ( NULL ); cout << "\n"; cout << " Normal end of execution.\n"; return 0; } void *H ( void *arg ) { int i; i = (long) arg; pthread_mutex_lock ( &mutex ); // Lock access to cH and cO variables if ( (cH > 0) && (cO > 0) ) { // I'm an H, have we the others? cH--; // Using an H cO--; // Using an O cout << "Soy un H, hice agua: " << i << endl; pthread_mutex_unlock ( &mutex ); //Free the mutex sem_post( &sH ); // Free the waiting thread sem_post( &sO ); // Free the waiting thread } else { cH++; // Increment the H count cout << "Soy un H, estoy esperando: " << i << endl; pthread_mutex_unlock ( &mutex ); // Free the mutex sem_wait( &sH ); // Wait for the others } pthread_exit ( ( void * ) 0 ); } void *O ( void *arg ) { int i; i = (long) arg; pthread_mutex_lock ( &mutex ); // Lock access to cH and cO variables if ( cH > 1 ) { // I'm an O, have we at least two H's? cH-=2; // We use two H's cout << "Soy un O, hice agua: " << i << endl; pthread_mutex_unlock ( &mutex ); //Free mutex sem_post( &sH ); // Free the waiting threads sem_post( &sH ); } else { cO++; // Increment O count, then wait cout << "Soy un O, estoy esperando: " << i << endl; pthread_mutex_unlock ( &mutex ); // Free mutex sem_wait( &sH ); // Wait for other threads } pthread_exit ( ( void * ) 0 ); // Finish this thread }