http://informatica.uv.es/iiguia/SO/lab/prac4/
#include
<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <pthread.h>
#include
"buffer.h"
int TAM=1024;
/***
*** Datos compartidos
***/
/* buffer compartido por productores y consumidores */
buffer_t *b;
/* mutex para exclusion mutua */
pthread_mutex_t mtx;
/* variable condicion para que esperen los productores */
pthread_cond_t cond_prod;
/* variable condicion para que esperen los consumidores */
pthread_cond_t cond_cons;
/* indicador para que los consumidores sepan que no quedan productores y
* que, por lo tanto, cuando el buffer se vacia deben terminar
* (no deben terminar inmediatamente, porque entonces podrian quedarse
* sin tratar las ltimas lineas depositadas por los productores) */
int terminar = 0;
/***
*** Funciones base de los hilos
***/
/*
* funcion base de los productores
* - cada productor copia linea a linea un fichero en el buffer compartido
* - el argumento es el puntero al nombre del fichero del que leer
*/
void *productor(void *arg)
{
printf ("Productor %lu fichero de entrada
%s\n", pthread_self(),(char *)arg);
FILE *f;
int fin;
char linea[TAM];
f = fopen((char *)arg,"r");
if (f == NULL)
{
perror("Error del
sistema");
printf("No se puede abrir
\"%s\" para leer\n\n",(char *)arg);
exit(1);
}
while (!fin)
{
if(fgets(linea,TAM,f)
!= NULL)
{
pthread_mutex_lock(&mtx);
// Obtener acceso exlusivo al buffer
while
(buf_lleno(b)) // espero mientras en buffer eet lleno
{
pthread_cond_wait(&cond_prod,
&mtx);
}
buf_poner(b,strdup(linea));
//Insertar linea en el buffer
pthread_cond_signal(&cond_cons);
pthread_mutex_unlock(&mtx);
}else
fin
=1;
}
fclose(f);
pthread_exit(0);
return 0;
}
/*
* funcion base de los consumidores
* - cada consumidor va volcando linea a linea el contenido del buffer
* en el fichero cuyo nombre se le pasa como parametro
*/
void *consumidor(void *arg)
{
char *linea;
FILE *f_out;
printf ("Consumidor%lu fichero de salida
%s\n", pthread_self(),(char *)arg);
f_out = fopen((char *)arg,"w");
while (!buf_vacio(b) || terminar!=1) //Mientras el
buffer este lleno o terminar este a 0
{
pthread_mutex_lock(&mtx);//El
acceso es exclusivo
while (buf_vacio(b) &&
terminar!=1)
{
pthread_cond_wait(&cond_cons,&mtx);//Si el buffer esta vacio que no lea
}
if(buf_vacio(b))
{
terminar
= 1;
pthread_mutex_unlock(&mtx);//Desbloquea
el acceso exclusivo
}else
{
linea =
buf_quitar(b);
pthread_cond_signal(&cond_prod);//Avisa
al productor por si quiere escribir
pthread_mutex_unlock(&mtx);
printf("Consumir : %s ",linea);
fprintf(f_out,"%s",linea);
free(linea);
}
}
fclose(f_out);
return NULL;
}
/***
*** Programa principal
***/
/*
* funcion para indicar como utilizar el programa
*/
static void uso(const char *prog)
{
fprintf(stderr,
"Uso: %s
fich_de_salida fich_de_entrada_1 [f2 [...]]\n",
prog);
exit(1);
}
/*
* funcion base del hilo principal del programa
*/
int main(int argc, char *argv[])
{
int i;
int argum =argc-2;
pthread_t p[argum];
if (argc < 3 ) // si no tiene tres parametros se ejecuta
uso/user1/Desktop/hilos.html#fichero-main-c
{
uso(argv[0]);
}
b = buf_crear(TAM);
pthread_mutex_init(&mtx,NULL);
pthread_cond_init(&cond_prod,NULL);
pthread_cond_init(&cond_cons,NULL);
for(i=0;i<argum;i++)
{
pthread_create(&p[i],NULL,productor,argv[i+2]);
}
pthread_create(&p[0],NULL,consumidor,argv[1]);
for (i = 1; i < argum; ++i)
{
pthread_join(p[i], NULL);
}
pthread_mutex_lock(&mtx);
terminar = 1;
pthread_cond_signal(&cond_cons);
pthread_mutex_unlock(&mtx);
pthread_join(p[0], NULL);
pthread_cond_destroy(&cond_prod);
pthread_cond_destroy(&cond_cons);
buf_imprimir(b);
return 0;
}