[C] Problemas con hotel de mascotas

¡Buenos días!
Antes de nada decir que he utilizado la búsqueda para ver si existía un Hilo Oficial de C, pero solo lo encontre de C#.
Si existe y no lo he encontrado, mis disculpas.

Al turrón:

Tengo un trabajo que consiste en un hotel de mascotas (trabajo Sistemas Operativos)
El caso es el hotel de mascotas, de inicio, tiene capacidad para atender a 6 clientes y 3 empleados, pero eso después se puede cambiar.
Los clientes pueden traer, o bien perros, o bien gatos y se diferenciaran mediante dos señales (SIGUSR1 para perros y SIGUSR2 para gatos).
Y un empleado de los 3, o de los que se eligan, ha de ser exclusivo para perros.
Hasta aquí mis dudas, os paso a continuación el código:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>

// Practica final I.
// Sistemas Operativos.

// *************************
// * INSTRUCCIONES DE USO! *
// *************************

// Para compilar este programa escribir:
//
//             gcc hotelMascotas.c -lpthread -o hotelMascotas

// Para ejecutar el programa hacer:
//
//             ./hotelMascotas &
//
// El numero que sale en la consola es el PID del proceso que se utilizara para enviar senyales al mismo!
// (ver abajo)

// *******************
// * Para subir nota *
// *******************
// Es posible pasar dos parametros al programa (se pueden pasar ambos, uno solo, o ninguno, y en cualquier orden!):
// -e NUMERO -> numero de empleados que atenderan llamadas
// -c NUMERO -> numero maximo de clientes en la cola (capacidad de la cola de clientes en espera)
// Esto corresponde al punto 3 (Asignación estática de recursos) para subir nota.
// Ejemplos:
//
//             ./hotelMascotas -e 5 &         
//
//             ./hotelMascotas -c 12 -e 5 &
//

// Al comenzar a ejecutarse, el programa queda a la espera de senyales:
// - Para poder enviar una senyal al mismo, necesitamos su PID, lo sacamos con el comando:
//
//             ps (y miramos el PID del proceso "hotelMascotas")
//
//      ... o mas directo, ejecutamos el comando:
//
//             ps | grep hotelMascotas | cut -d'p' -f1
//
// - Una vez se tiene el PID, se envia la senyal que queramos al programa con kill -NUMERO_SEGNYAL PID
//   El programa reconoce las siguientes senyales:
//
//     - SIGUSR1 (10) : simula la llegada de una llamada de un cliente con perro
//     - SIGUSR2 (11) : simula la llegada de una llamada de un cliente con gato
//
// Ejemplos de como enviar llamadas con un solo comando:
//
//        pid=`ps | grep hotelMascotas | cut -d'p' -f1`; kill -10 $pid

// *****************************************************
// * Definicion de constantes y declaraciones globales *
// *****************************************************

// Valores por defecto (ver pdf)

const int NUMERO_CLIENTES_POR_DEFECTO = 6;
const int NUMERO_EMPLEADOS_POR_DEFECTO = 3;

// Semaforos:
// - mutexCola sera el semaforo para la cola de clientes
// - mutexLog sera el semaforo para evitar que dos procesos intenten escribir una linea de log a la vez
pthread_mutex_t mutexCola;
pthread_mutex_t mutexLog;


// Numero de clientes del hotel de mascotas en un momento dado
int numeroClientes;

// Numero de clientes que han llamado al hotel de mascotas hasta el momento
int numeroClientesQueHanLlamado;

// Maximo numero de clientes que puede atender el hotel de mascotas (podra ser modificado)
int maximoNumeroClientes;

typedef struct {

  // Identificador de usuario
  int id;
  // Flag que indica si un cliente esta siendo atendido o no
  int atendido;
  // Tiempo en segundos que el cliente ha sido atendido por un empleado
  int segundosAtendido;
  // Tiempo en segundos que el cliente tuvo que esperar antes de ser atendido por un empleado
  int segundosEsperados;
  // Hilo que ejecuta las acciones (esperar a que le atiendan) de un cliente
  pthread_t hilo;

} informacionCliente;

// Lista de los Clientes en espera en el hotel (inicialmente habra espacio para 10 clientes, pero podra ser modificado).
informacionCliente *listaClientes;

// Numero de empleados que trabajan en el hotel de mascotas
int numeroEmpleados;

typedef struct {

  // Identificador de empleado
  int id;
  // Hilo que ejecuta las acciones de un empleado
  pthread_t hilo;

} informacionEmpleado;

// Lista de los empleados del hotel (inicialmente habra espacio para 3 clientes, pero podra ser modificado).
informacionEmpleado *listaEmpleados;

// Fichero de log
FILE *ficheroLog;

// Nombre del fichero de log
const char *NOMBRE_FICHERO_LOG = "hotelMascotas.log";

// *****************************************************
// * Funciones y procedimientos *
// *****************************************************

// Escribe una nueva linea de log con el mensaje e identificador
// recibidos como parametros.
void escribirNuevaLineaLog(char *identificador, char *mensaje) {

  // Protegemos mediante el semaforo de log
  pthread_mutex_lock(&mutexLog);

  // Calculamos la hora actual
  time_t now = time(0);
  struct tm *tlocal = localtime(&now);
  char stnow[19];
  strftime(stnow, 19, "%d/%m/%y %H:%M:%S", tlocal);
  // Escribimos en el log
  ficheroLog = fopen(NOMBRE_FICHERO_LOG, "a");
  fprintf(ficheroLog, "[%s] %s: %s\n", stnow, identificador, mensaje);
  fclose(ficheroLog);

  // Desbloqueamos el semaforo
  pthread_mutex_unlock(&mutexLog);

}

// Elimina de listaClientes el cliente en el indice indicado. Si no existiera, no se hace nada
void eliminarClienteDeLaLista(int indice) {

  // Quien llame a esta parte del codigo debera protegerse tambien para evitar que se intenten eliminar o incluir clientes al mismo tiempo
  int i = 0;

  // Para borrar, asignamos a la posicion "i" los datos de la posicion "i+1","i+1" los de la posicion "i+2" y asi hasta el final.
  for (i=indice; i<numeroClientes-1;i++)
       listaClientes[i] = listaClientes[i+1];

  // El ultimo elemento de la lista pasa a estar vacio
  listaClientes[numeroClientes-1].id = 0;
  listaClientes[numeroClientes-1].hilo = 0;

  // Se reduce en 1 el numero de clientes, y tambien el valor del indice 'i'
  // ya que acabamos de eliminar el elemento al que apuntabda
  numeroClientes--;

}

// Funcion que obtiene el indice que ocupa un cliente en la cola dado su identificador (llamada protegida por un semaforo).

int obtenerIndiceEnLaCola (int idCliente) {

  int i = 0;

  for (i = 0; i < numeroClientes; i++)
    if (listaClientes[i].id == idCliente)
      return i;
 
  // Si llegamos aqui el cliente no esta en la lista: devolvemos -1
  return -1;
}

// Funcion que devuelve el numero de cliente desatendidos
int obtenerNumeroClientesDesatendidos() {

  int numeroDesatendidos = 0;

  int i = 0;

  pthread_mutex_lock(&mutexCola);

  for (i = 0; i < numeroClientes; i++)
    //El cliente que este desatendido debe de tener flag "atendido" y segundosAtendido = 0 para evitar que cuando un cliente deja de ser atendido
    //(su flag "atendido" seria 0 en ese momento) sea atendido por otro empleado.
   
    if ((listaClientes[i].atendido == 0) && (listaClientes[i].segundosAtendido == 0))
      numeroDesatendidos++;

  pthread_mutex_unlock(&mutexCola);

  return numeroDesatendidos;

}

// Funcion que ejecuta cada uno de los empleados (que seran a su vez hilos)
void *accionesEmpleado(void *idEmpleado) {

  // Variable para poder combinar caracteres y numeros antes de incluir la linea en el log
  char mensajeLog[200];

  // Variable para saber si un empleado tiene un cliente al que atender
  int tengoCliente = 0;

  // Datos del cliente al que se atendera (sera una copia del cliente en la cola)
  informacionCliente infoCliente;

  // En el parametro idCliente recibimos el identificador del empleado, pero hay que hacer un cast
  int identificador = (int) idEmpleado;

  // El identificador del empleado completo sera (ver especificacion) la palabra "empleado_" seguida de este numero
  char identificadorCompleto[9];
  sprintf(identificadorCompleto,"Empleado_%d", identificador);

  // El empleado queda en un bucle infinito esperando llamadas entrante y atendiendolas en orden de antiguedad cuando se produzcan.
  while (1) {

    sprintf(mensajeLog, "Permanece a la espera para atender una llamada");

    escribirNuevaLineaLog(identificadorCompleto, mensajeLog);

    // Buscamos el cliente que lleva mas tiempo esperando (que sera el de menor valor del campo .id de la listaClientes).
     while (obtenerNumeroClientesDesatendidos() <= 0) {
      sleep(1);
    }

    // Protegemos esta zona del codigo para evitar que varios empleados "se lancen" sobre el mismo cliente
    pthread_mutex_lock(&mutexCola);

    // Sabemos que hay al menos un cliente desatendido en la lista.
    // Cogemos el que lleva mas tiempo en la cola (ya que es una cola FIFO):
    // Empezamos a buscar en el indice 0
    int indice = 0;

    // El cliente a atender no puede estar siendo atendido (atendido == 1) ni tampoco puede acabar de ser atendido (segundosAtendido > 0)
    while ((indice < numeroClientes) && ((listaClientes[indice].atendido == 1) || (listaClientes[indice].segundosAtendido > 0))) {
      indice++;
    }

    // Si encontramos algun cliente sin atender, lo atendemos
    if (listaClientes[indice].atendido == 0) {

      // Indicamos que hemos encontrado un cliente que atender!
      tengoCliente = 1;

      // Un empleado atiende a un cliente un tiempo aleatorio entre 30 y 50 segundos (ver pdf)
      // Con rand()%21  generamos un numero aleatorio entre 0 y 20, y le sumamos 30 para que quede entre 30 y 50 segundos
      listaClientes[indice].segundosAtendido = rand()%21 + 30;

      // Registramos la hora de inicio de la conversacion
      sprintf(mensajeLog, "Comienza a atender la llamada de Cliente_%d", listaClientes[indice].id);
      escribirNuevaLineaLog(identificadorCompleto, mensajeLog); 
     
      // Cambiamos el flag
      listaClientes[indice].atendido = 1;

      // Guardamos estos datos de cliente en la variable local infoCliente
      infoCliente = listaClientes[indice];

    }

    // ya paso el peligro de concurrencia, desbloqueamos el mutex
    pthread_mutex_unlock(&mutexCola);

    if (tengoCliente) {

      sleep(infoCliente.segundosAtendido);   

      // Registramos la hora de finalizacion de la conversacion
      sprintf(mensajeLog, "La llamada de Cliente_%d ha finalizado tras %d segundos siendo atendido", infoCliente.id, infoCliente.segundosAtendido);
      escribirNuevaLineaLog(identificadorCompleto, mensajeLog);

      // Una vez se termina de atender al cliente, volvemos a poner el flag de atendido a false para que el hilo del cliente pueda terminar
      pthread_mutex_lock(&mutexCola);
     
      // Hay que volver a buscar el indice del cliente, no sea que haya cambiado de posicion en la cola
      // en caso de que otros clientes hayan salido ya de esta
      indice = obtenerIndiceEnLaCola (infoCliente.id);
      listaClientes[indice].atendido = 0;
     
      pthread_mutex_unlock(&mutexCola);

    }

    // Una vez se termina de atender al cliente, el empleado queda sin cliente.
    tengoCliente = 0;

  } // Fin del bucle infinito de atencion de llamdas

  // Si alguna vez llegaramos a esta linea (que nunca sera asi), terminariamos el hilo
  pthread_exit(NULL);

}

// Funcion que indica si un cliente (dado su identificador) esta atendido o no
int estaAtendido (int identificador) {

   int atendido = 0;

  // Busca en la lista el cliente con ese identificador y comprueba si esta atendido.
  // Como todo lo que busque en la cola requiere semaforo
  pthread_mutex_lock(&mutexCola);

  int i = 0;

  for (i = 0; i < numeroClientes; i++)
    if ((listaClientes[i].id == identificador) && (listaClientes[i].atendido == 1))
      atendido = 1;
 
  pthread_mutex_unlock(&mutexCola);

  return atendido;

}

// Funcion que indica el numero de segundos que el cliente ha sido atendido
int obtenerSegundosAtendido (int identificador) {

  int segundosAtendido = 0;

  pthread_mutex_lock(&mutexCola);

  int i = 0;

  for (i = 0; i < numeroClientes; i++)
    if (listaClientes[i].id == identificador)
      segundosAtendido = listaClientes[i].segundosAtendido;


  pthread_mutex_unlock(&mutexCola);

  return segundosAtendido;

}

void *accionesCliente(void *idCliente) {

  // Variable para poder combinar caracteres y numeros antes de incluir la linea en el log
  char mensajeLog[200];

  // En el parametro idCliente recibimos el identificador del clinte, pero hay que hacer un cast
  int identificador = (int) idCliente;

  // El identificador del cliente completo sera (ver pdf) la palabra "cliente_" seguida de este numero
  char identificadorCompleto[9];
  sprintf(identificadorCompleto,"Cliente_%d", identificador);

  sprintf(mensajeLog, "Esta a la espera de ser antendido");

  escribirNuevaLineaLog(identificadorCompleto, mensajeLog);

  // Segundos de duracion de la llamada (si es que llegan a atenderle)
  int numeroSegundosConversacion = 0;
 
  // Calculamos tiempo de espera (tiempo que el cliente esperara antes de colgar)
  // (ver pdf)
  int numeroSegundosEsperados = 0;
  int maximoSegundosAEsperar;

  //- El 20% de los usuarios cuelgan transcurridos 2 minutos.
  //- El 30% de los usuarios cuelgan transcurridos 3 minutos.
  //- El resto de los usuarios cuelgan transcurridos 5 minutos.

  int numeroDel0al100 = rand()%100;

  if (numeroDel0al100 < 20)
    maximoSegundosAEsperar = 120;
  else  if ((numeroDel0al100 >= 20) && (numeroDel0al100 < 30))
    maximoSegundosAEsperar = 180;
  else
    maximoSegundosAEsperar = 300;

  // Esperamos segundo a segundo hasta que lleguemos al maximo de segundos a esperar
  // o hasta que un empleado nos atienda
  while ((numeroSegundosEsperados < maximoSegundosAEsperar)&&(!estaAtendido(identificador))) {
    sleep(1);
    numeroSegundosEsperados++;
  }

  // Si se llega hasta aqui, es porque ha colgado o porque le han atendido:
  // Si numeroSegundosEsperados < maximoSegundosAEsperar = cliente atendido.
   
  // Primero almacenamos el tiempo que se ha esperado realmente.
  // hay que volver a buscar el indice que ocupamos en la cola por si esta ha cambiado
  pthread_mutex_lock(&mutexCola);

  int indice = obtenerIndiceEnLaCola (identificador);
  listaClientes[indice].segundosEsperados = numeroSegundosEsperados;

  pthread_mutex_unlock(&mutexCola);

  if (numeroSegundosEsperados >= maximoSegundosAEsperar) {

    sprintf(mensajeLog, "Ha colgado tras esperar %d segundos.",numeroSegundosEsperados);

  }
  else {
    // Un empleado esta atendiendo al hilo: esperamos a que termine de atendernos
    while (estaAtendido(identificador))
      sleep (1);

    // Indicamos que el tiempo total de llamada para el hilo
    sprintf(mensajeLog, "La duracion total de la llamada ha sido %d segundos de espera y %d segundos siendo atendido.",  numeroSegundosEsperados, obtenerSegundosAtendido(identificador));


  }

  // Imprimimos el mensaje de log que corresponda y terminamos
  escribirNuevaLineaLog(identificadorCompleto, mensajeLog);

  pthread_mutex_lock(&mutexCola);

  // Hay que volver a buscar el indice del cliente, no sea que haya cambiado de posicion en la cola
  // en caso de que otros clientes hayan salido ya de esta
  indice = obtenerIndiceEnLaCola (identificador);
  eliminarClienteDeLaLista(indice);

  pthread_mutex_unlock(&mutexCola);

  pthread_exit(NULL);
}

void perro() {

  // Todo este procedimiento debe protegerse mediantes semaforo.
  pthread_mutex_lock(&mutexCola);

  // Comprobamos si hay espacio en la lista de clientes (si no lo hay, se pone en espera)
  if (numeroClientes < maximoNumeroClientes) {
   
      // El identificador del cliente coincide con el numero de clientes + 1 (evitar que el primer cliente tenga id = 0).
   
    listaClientes[numeroClientes].id = numeroClientesQueHanLlamado + 1;
    listaClientes[numeroClientes].atendido = 0;
    listaClientes[numeroClientes].segundosAtendido = 0;
    listaClientes[numeroClientes].segundosEsperados = 0;
    // Creamos un hilo cliente (en el que permanecera a la espera y puede llegar a colgar)   
    pthread_create(&listaClientes[numeroClientes].hilo, NULL, accionesCliente, (void *)listaClientes[numeroClientes].id);
    // Incrementamos numero de clientes
    numeroClientes++;
    // y el numero de clientes que han llamado
    numeroClientesQueHanLlamado++;

  }
  else {
    // No habia espacio!!
    // por lo demas, la llamada se ingnora
  }

  // Se debloquea el semaforo
  pthread_mutex_unlock(&mutexCola);

}

void gato() {

  // Todo este procedimiento debe protegerse mediantes semaforo.
  pthread_mutex_lock(&mutexCola);

  // Comprobamos si hay espacio en la lista de clientes (si no lo hay, se pone en espera)
  if (numeroClientes < maximoNumeroClientes) {
   
     // El identificador del cliente coincide con el numero de clientes + 1 (evitar que el primer cliente tenga id = 0).
   
    listaClientes[numeroClientes].id = numeroClientesQueHanLlamado + 1;
    listaClientes[numeroClientes].atendido = 0;
    listaClientes[numeroClientes].segundosAtendido = 0;
    listaClientes[numeroClientes].segundosEsperados = 0;
    // Creamos un hilo cliente (en el que permanecera a la espera y puede llegar a colgar)   
    pthread_create(&listaClientes[numeroClientes].hilo, NULL, accionesCliente, (void *)listaClientes[numeroClientes].id);
    // Incrementamos numero de clientes
    numeroClientes++;
    // y el numero de clientes que han llamado
    numeroClientesQueHanLlamado++;

  }
  else {
    // No habia espacio!!
    // por lo demas, la llamada se ingnora
  }

  // Se debloquea el semaforo
  pthread_mutex_unlock(&mutexCola);

}

void crearHilosEmpleados() {

  // Creamos un hilo para cada empleado
  int i = 0;

  for (i = 0; i < numeroEmpleados; i++)
    pthread_create(&listaEmpleados[i].hilo, NULL, accionesEmpleado, (void *)listaEmpleados[i].id);

}

void inicializarListaClientes() {

  // Reserva dinamica de memoria para la lista de clientes por si cambia su tamanio en el futuro
  listaClientes = (informacionCliente *)malloc(maximoNumeroClientes*sizeof(informacionCliente)); 

  int i = 0;

  for (i = 0; i < maximoNumeroClientes; i++){
    // inicializamos el identificador a 0
    listaClientes[i].id = 0;
    listaClientes[i].atendido = 0;
    listaClientes[i].segundosAtendido = 0;
    listaClientes[i].segundosEsperados = 0;
  }

}

void inicializarListaEmpleados() {

  // Reserva dinamica de memoria para la lista de empleados por si cambia su tamanyo en el futuro
  listaEmpleados = (informacionEmpleado *)malloc(numeroEmpleados*sizeof(informacionEmpleado)); 

  int i = 0;

  for (i = 0; i < numeroEmpleados; i++) {
   
   // Los empleados, a diferencia de los clientes, existen desde el principio
       // y nunca dejan de existir durate la duracion del programa, por lo que indicamos ya su identificador real.

    listaEmpleados[i].id = i + 1;

  } 

}


void cambiarMaximoNumeroClientes (int nuevoMaximo) {

  maximoNumeroClientes = nuevoMaximo;
 
  // Como va a cambiar el numero de clientes de listaClientes,
  // liberamos la lista anterior y la creamos de nuevo
  free(listaClientes);
  inicializarListaClientes(); 

  //Indicamos que, al reiniciar la lista, se han perdido los clientes.
  numeroClientes = 0;
  numeroClientesQueHanLlamado = 0;

}

//Funcion nueva para cambiar el maximo numero de empleados (07/01/2013)
void cambiarMaximoNumeroEmpleados (int NuevoMaximo1) {
   if(NuevoMaximo1 > 3){
      int MaximoNumeroEmpleados = NuevoMaximo1;
      // Como va a cambiar el numero de empleados de listaEmpleados,
        // liberamos la lista anterior y la creamos de nuevo
        free(listaEmpleados);        
        inicializarListaEmpleados();
        numeroEmpleados = 0;
      char mensaje[250];
      sprintf(mensaje,"El numero de empleados es ahora de %d .", MaximoNumeroEmpleados);
      escribirNuevaLineaLog("main", mensaje);

  }
}
// Devuelve 1 si todos los caracteres de la cadena recibida son numeros
// Para comprobar si un caracter es numero o no, el codigo esta sacado de aqui:
// http://www.dreamincode.net/forums/topic/53355-c-check-if-variable-is-integer/
int esNumero (char *cadena) {

  // Si atoi (ASCII to integer) da distinto de 0, es porque es un numero, y devolveriamos 1 (esNumero = true).
  // Si da 0, es una letra (o el numero 0, pero ese no nos sirve), asi que devolveriamos 0.
  if (atoi(cadena) != 0)
    return 1;
  else
    return 0;
 
}

// Inicializa las variables.
// Implementamos la funcionalidad extra 3: asignacion estatica de recursos,
// es decir, permitimos pasar como parametros numero de llamadas y numero de empleados
// (ver instrucciones al principio del programa)
void inicializarVariables(int argc, char *argv[]) {
 
  // Analizamos el numero de argumentos recibidos.
  // Aceptariamos:
  // - 1 solo argumento (que seria el propio nombre del programa: ./hotelMascotas)
  // - 3 argumentos: o bien ./hotelMascotas -e NUMERO, o bien ./hotelMascotas -c NUMERO,
  // donde -e indica "empleados" (numero de empleados) y -c indica "clientes" (numero maximo de clientes en la cola),
  // por ejemplo al ejecutar ./hotelMascotas -e 5
  // - 5 argumentos: ./hotelMascotas -e NUMERO -c OTRO_NUMERO

  // Almacenamos en un flag si los argumentos recibidos son correctos
  int argumentosCorrectos = 0;

  if (argc == 3) {

    // Si hay tres argumentos, el primero sera el nombre del programa, el segundo debera ser "-c" o "-e"
    // y el tercero debera ser un numero.   
    // Para comparar cadenas de caracteres:
    // http://www.wikihow.com/Compare-Two-Strings-in-C-Programming
    if ((strncmp(argv[1],"-c",100) == 0 || strncmp (argv[1],"-e",100) == 0) && esNumero(argv[2]))  {
   
      argumentosCorrectos = 1;

      if (strncmp(argv[1],"-c",100) == 0) {
        // Si nos dan los clientes, ponemos los empleados al valor por defecto
        maximoNumeroClientes = atoi(argv[2]);
        numeroEmpleados = NUMERO_EMPLEADOS_POR_DEFECTO;
      }
      else {
        maximoNumeroClientes = NUMERO_CLIENTES_POR_DEFECTO;
        numeroEmpleados = atoi(argv[2]);
      }
    }

  }
  else if (argc == 5) {

    // Cinco argumentos: el de indice 1 y 3 son -c y -d (o -d y -c) y los de indice 2 y 4 son numeros.
    if (
          ((strncmp(argv[1],"-c",100) == 0 && strncmp (argv[3],"-e",100) == 0) || (strncmp(argv[1],"-e",100) == 0 && strncmp (argv[3],"-c",100) == 0)) &&
          esNumero(argv[2]) && esNumero(argv[4]) 
       ) {

      argumentosCorrectos = 1;

      // Respetamos el orden en que nos pasaron los argumentos
      if (strncmp(argv[1],"-c",100) == 0) {
        maximoNumeroClientes = atoi(argv[2]);
        numeroEmpleados = atoi(argv[4]);
      }
      else {
        maximoNumeroClientes = atoi(argv[4]);
        numeroEmpleados = atoi(argv[2]);
      }

    }

  }

  // Si los argumentos no eran correctos (o si ni siquiera habia),
  // inicializamos a los valores por defecto: 6 clientes y 3 empleados
  if (argumentosCorrectos == 0) {

    maximoNumeroClientes = NUMERO_CLIENTES_POR_DEFECTO;
    numeroEmpleados = NUMERO_EMPLEADOS_POR_DEFECTO;

  }

// Creamos semaforos
  pthread_mutex_init(&mutexCola,NULL);
  pthread_mutex_init(&mutexLog,NULL);

  // Clientes
  numeroClientes = 0;
  numeroClientesQueHanLlamado = 0;

  inicializarListaClientes();

  // Empleados
  inicializarListaEmpleados();

  // La inicializacion del fichero de log supone crear dicho archivo (si ya existiera, se borraria)
  // y luego cerrarlo inmediatamente.
  // El procedimiento escribirNuevaLineaLog se encarga de abrirlo y cerrarlo posteriormente para cada linea
  // de log a escribir.
  ficheroLog=fopen (NOMBRE_FICHERO_LOG, "wt");
  fclose(ficheroLog);

  // Indicamos que se ha inicializado todo correctamente (por consola y al log)
  char mensaje[250];
  sprintf(mensaje,"El hotel de mascotas ha sido inicializado con %d empleados y capacidad para %d clientes", numeroEmpleados, maximoNumeroClientes);
  escribirNuevaLineaLog("main", mensaje);

  printf ("\n");
  printf ("%s\n",mensaje);
  printf ("\n");
  // Si no han pasado parametros, recordamos que pueden hacerlo!
  if (argumentosCorrectos == 0) {
    printf ("  - Recuerda que puedes indicar al programa el numero de empleados (-e) y de clientes (-c) en cola (instrucciones disponibles en el codigo):\n");
    printf ("          ./hotelMascotas -c 20 -e 5 &\n");
    printf ("\n");
  }
  printf ("  - Si has arrancado el programa con '&' (./hotelMascotas &), puedes simular llamadas entrantes escribiendo en la consola: \n");
  printf ("          pid=`ps | grep hotelMascotas | cut -d'p' -f1`; kill -10 $pid\n");

}

// main, con la declaracion y parametros indicados en la practica 5
// Recibimos parametros, inicializamos lo que haga falta y creamos los hilos
int main (int argc, char *argv[], char *envp[]) {

 
  // Inicializamos un generador de numeros aleatorios para poder simular cuando cuelgan los clientes
  // (ver accionesCliente y explicacion en http://en.kioskea.net/faq/878-generating-random-numbers-with-rand y
  // http://www.cprogramming.com/tutorial/random.html)
  //randomize();
  // Usamos como semilla la hora actual
  srand(time(0));

  // Borramos texto en la consola (esto solo funciona en linux?)
  system("clear");

  // Inicializamos variables.
  // Implementamos la funcionalidad extra 3: asignacion estatica de recursos
  inicializarVariables(argc, argv);

  // Creacion de los hilos de los empleados
  crearHilosEmpleados();

  // El main permanece (indefinidamente) a la espera de la senial SIGUSR1 o SIGUSR2, que interpreta como una nueva llamada.
      // SIGUSR1 = el cliente viene con perro.
      // SIGUSR2 = el cliente viene con gato.
    
          if (signal(SIGUSR1, perro)==SIG_ERR) {
              exit(-1);
           }
      if (signal(SIGUSR2, gato)==SIG_ERR) {
         exit(-1);
           }
  // Nos quedamos aqui indefinidamente para que no termine el programa
  while (1) {
    pause();
  }
}


Y las instrucciones, pues me temo que no me he explicado bien:

https://www.dropbox.com/s/gg11q7skd24x1 ... FinalI.pdf

Uno de los problemas ante los que me encuentro y no consigo saber porque es que, de forma aleatoria, aparece un cliente_0 de la nada y ya no funciona más, aparece violación de segmento en la terminal y c'est fini.
Otro de los problemas es que no me funciona la asignación dinámica de recursos para que cuando ejecute y cambie el número de empleados por < 3 no me funcione (y para más inri ni siquiera pasa los cambios por el LOG y por la terminal como le he puesto, que inutilidad por Dios XD )
Y por último, el empleado exclusivo de perros (señal SIGUSR1) Ahí ya si que no tengo ni idea [buuuaaaa]

¿Alguna sugerencia o idea?

Gracias :-|
0 respuestas