// adquirir_datos.cpp - Utilización de la clase CHilo
#include <iostream>
#include "hilo.h"
using namespace std;

const int MAX_MUESTRAS = 10; // elementos de la matriz de datos

class CAdquirir_datos : public CHilo
{
  private:
    static int muestras[MAX_MUESTRAS]; // matriz de datos
    static int ind; // índice del primer elemento vacío
    static pthread_mutex_t mutex_adquirir; // exclusión mutua
  public:
    CAdquirir_datos(string nombre = "") : 
    CHilo(nombre)
    {
      // Iniciar los atributos
      ind = 0;
      fill(muestras, muestras+MAX_MUESTRAS, 0);
      int cod = pthread_mutex_init(&mutex_adquirir, 0);
      if (cod) throw(string("pthread_mutex_init"));
    }
    
    void *CAdquirir_datos::fnHilo()
    {
      int x = 0, cod;
      do
      {
        cod = pthread_mutex_lock(&mutex_adquirir);
        if (cod) throw(string("pthread_mutex_lock"));
        
        if (ind >= MAX_MUESTRAS) return obtener_id();
        x = rand();  // adquirir un dato
        cout << "hilo-" << obtener_nombre()
             << " tomó la muestra " << ind << endl;
        muestras[ind] = x;
        ind++; // incrementar el índice de la matriz
        
        cod = pthread_mutex_unlock(&mutex_adquirir);
        if (cod) throw(string("pthread_mutex_unlock"));
      }
      while (ind < MAX_MUESTRAS);
      return 0;
    }
};

// Iniciar los atributos static de CAdquirir_datos
int CAdquirir_datos::muestras[MAX_MUESTRAS];
int CAdquirir_datos::ind;
pthread_mutex_t CAdquirir_datos::mutex_adquirir;

int main()
{
  const int NHILOS = 2; // número de hilos
  int i;
  char nomHilo[10];
  CAdquirir_datos hilo[NHILOS];
  
  try
  {
    // Crear los hilos
    for (i = 0; i < NHILOS; i++)
    {
      sprintf(nomHilo, "%d", i);
      hilo[i].asignar_nombre(string(nomHilo));
      hilo[i].iniciar();
    }

    // Esperar a que los hilos trabajadores terminen
    for (i = 0; i < NHILOS; i++)
      hilo[i].esperar_finalizacion();
  }
  catch(string& msj)
  {
    cout << msj << endl;
  }
  
  system("pause");
}

