Universidad de Costa Rica

Escuela de Ciencias de la Computación e Informática

CI-0122 Sistemas operativos

Ejemplos

CI0122 / Ejemplos / pthreads / h2o


// Compile with g++ h20.cc sempt.cc -lpthread
//
#include <cstdlib>
#include <iostream>
#include "synch.h"

using namespace std;

#define NUMTHRDS 100
int status;
int n = 256;
pthread_t thds[NUMTHRDS];
Mutex * mutex;

SemPT * 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;

  sO = new SemPT( 0 );
  sH = new SemPT( 0 );
  mutex = new Mutex();

  pthread_attr_t attr;
  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_exit ( NULL );

  cout << "\n";
  cout << "  Normal end of execution.\n";

  delete mutex;
  delete sO;
  delete sH;

  return 0;
}


void *H ( void *arg ) {

   int i;

   i = (long) arg;

   mutex->Lock();		// 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;
      mutex->Unlock();		//Free the mutex
      sH->Signal();		// Free the waiting thread
      sO->Signal();		// Free the waiting thread
   } else {
      cH++;			// Increment the H count
      cout << "Soy un H, estoy esperando: " << i << endl;
      mutex->Unlock();		//Free the mutex
      sH->Wait();		// Wait for the others
   }

   pthread_exit ( ( void * ) 0 );
}


void *O ( void *arg ) {

   int i;

   i = (long) arg;

   mutex->Lock();	// 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;
      mutex->Unlock();	//Free the mutex
      sH->Signal();	// Free the waiting threads
      sH->Signal();
   } else {
      cO++;		// Increment O count, then wait
      cout << "Soy un O, estoy esperando: " << i << endl;
      mutex->Unlock();	//Free the mutex
      sH->Wait();	// Wait for other threads
   }

   pthread_exit ( ( void * ) 0 );	// Finish this thread
}