#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <semaphore.h>
#define Max_Trabajo 60 // El número máximo de hebras Trabajos.
// Prototipos de funciones...
void *Trabajos(void *num);
void *servidor(void *);
void rango_espera(int secs);
//Se definen los semaforos.
//El semaforo colaimpresion pone el limite del numero de Trabajos que se permiten ingresar al cuarto de espera en un tiempo determinado.
sem_t colaimpresion;
// Ocupar_servidor asegura la mutua exclusividad en el acceso al uso del servidor.
sem_t Ocupar_servidor;
// DescansaServidor es usada para permitir que el servidor descanse hasta que llegue el Trabajo.
sem_t DescansaServidor;
// MantenerTrabajo es usada para hacer que el Trabajo espere hasta que el servidor haya imprimido el documento.
sem_t MantenerTrabajo;
// Bandera para la hebra del servidor cuando todos los Trabajos han sido atentidos.
int Todohecho = 0;
int TrabajosEsperandoServidor=0;
int numEspacios=1;
int main(int argc, char *argv[])
{
int i;
pthread_t btid;
pthread_t tid[Max_Trabajo];
int numTrabajos;
int Numero[Max_Trabajo];
printf("El ńumero maximo de Trabajos es 60. Ingresa el numero de Trabajos.\n");
do{
scanf("%d",&numTrabajos
);
if(numTrabajos
> Max_Trabajo
)printf("El nº de Trabajos debe ser menor a %d, ingrese nº de Trabajos.\n",Max_Trabajo
);
}while(numTrabajos>Max_Trabajo);
if (numTrabajos > Max_Trabajo) {
printf("El Maximo numero de Trabajos es %d.\n", Max_Trabajo
); /******system("PAUSE");*****************/
return 0;
}
printf("Tenemos un servidor que imprime documentos.\n"); for (i = 0; i < Max_Trabajo; i++) {
Numero[i] = i;
}
// Se inicializa el semaforo con valores iniciales...
sem_init(&colaimpresion, 0, numEspacios);
sem_init(&Ocupar_servidor, 0, 1);
sem_init(&DescansaServidor, 0, 0);
sem_init(&MantenerTrabajo, 0, 0);
// Se Crea el servidor.
pthread_create(&btid, NULL, servidor, NULL);
// Se Crea el Trabajo.
for (i = 0; i < numTrabajos; i++) {
pthread_create(&tid[i], NULL, Trabajos, (void *)&Numero[i]);
}
// Se juntan las hebras a esperar que las otras terminen.
for (i = 0; i < numTrabajos; i++) {
pthread_join(tid[i],NULL);
}
// Cuando todos los Trabajos hayan terminado, se elimina la hebra servidor.
Todohecho = 1;
sem_post(&DescansaServidor); // Se despierta al servidor en la salida.
pthread_join(btid,NULL);
return 0;
}
void *Trabajos(void *Numero) {
int num = *(int *)Numero; // periodo de tiempo aleatorio para llegar.
printf("hebra %d creada\n", num
); rango_espera(5);
if(numEspacios
+1==TrabajosEsperandoServidor
)printf("Trabajo %d intenta ingresar a la cola de impresion\nEl Trabajo desiste de ingresar a la cola porque hay muchos trabajos\n", num
); // Espere hasta que sea prudente ingresar a la cola de impresion... sem_wait(&colaimpresion);
printf("Trabajo %d intenta ingresar a la cola de impresion \nTrabajo %d entra a la cola de impresion.\n************************************Hay %d Trabajos esperando a ocupar el servidor \n", num
, num
,++TrabajosEsperandoServidor
); // Esperar a que el servidor este libre..
//printf("*****************************************\n");
// printf("**Hay %d Trabajos en la cola de impresion **\n",TrabajosEsperandoServidor);
// printf("*****************************************\n");
sleep(10);
sem_wait(&Ocupar_servidor); // Si el servidor está libre entonces un trabajo aprovecha.
sem_post(&colaimpresion); // Despierta el servidor...
printf("Trabajo %d ocupa el servidor.\n", num
); sem_post(&DescansaServidor); // Espera a que el servidor termine de imprimir el trabajo.
sem_wait(&MantenerTrabajo); // Deja de ocupar el servidor.
sem_post(&Ocupar_servidor);
printf("Trabajo %d deja de ocupar el servidor.\n************************************Hay %d Trabajos intentando ocupar el servidor\n", num
,--TrabajosEsperandoServidor
);
// printf("*****************************************\n");
// printf("**Hay %d Trabajos en la cola de impresion **\n",TrabajosEsperandoServidor);
//printf("*****************************************\n");
sleep(10);
}
void *servidor(void *junk)
{
// Mientras todavía hayan Trabajos que atender... El servidor es omniciente y puede decir si hay Trabajos aún en el camino a su tienda.
while (!Todohecho) { // Esperar hasta que alguien llegue y te despierte..
if( TrabajosEsperandoServidor
==0 ) printf("el servidor esta esperando\n"); sem_wait(&DescansaServidor); // Omitir todo esto al final...
if (!Todohecho)
{ // Tomar un monto aleatorio de tiempo para imprimir el Trabajo..
printf("el servidor esta imprimiendo el documento\n"); rango_espera(3);
printf("el servidor ha terminado de imprimir el documento.\n"); // Se libera al Trabajo cuando se haya imprimido el documento... sem_post(&MantenerTrabajo);
}
else {
printf("El servidor ha terminado con la cola de impresion.\n"); }
}
}
void rango_espera(int secs) {
int len = 1; // Se genera un numero arbitrario...
sleep(len);
}