#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <string.h>
char MUTEX[128]="semaforo.txt";
int MAX_CADENA=128;
int i;
int num_barberos;
int num_sillas;
int num_clientes;
int *pid_barberos;
int cespera;
int *clientes_espera;
char menasaje[64];
int CLIENTES;
int BARBEROS;
void mostarMensaje(char *quien, char *que);
void Pb(char *nombre) {
int df;
while((df=open(nombre, O_CREAT | O_EXCL, 0777))==-1);
close(df);
}
void Vb(char *nombre) {
unlink(nombre);
}
int semcall(int semaforo, int operacion);
i
nt inicia(int valor) {
int id;
union semun {
int val;
struct semid_ds *buf;
ushort *array;
} arg;
if((id=semget(IPC_PRIVATE, 1, (IPC_CREAT|0666)))==-1) {
perror("Error al crear el semforo.");
return -1;
}
arg.val=valor;
if (semctl(id,0,SETVAL,arg)== -1) {
perror("Error al inicializar el semaforo.");
return -1;
}
return id;
}
void P(int semaforo) {
if(semcall(semaforo,-1)==-1) {
perror("Error en operacin P.");
}
}
void V(int semaforo) {
if(semcall(semaforo,1)==-1) {
perror("Error en operacin V.");
}
}
int semcall(int semaforo, int operacion) {
struct sembuf sb;
sb.sem_num=0;
sb.sem_op=operacion;
sb.sem_flg=0;
return semop(semaforo,&sb,1);
}
void borra_s(int semaforo) {
if(semctl(semaforo,0,IPC_RMID,0)==-1) {
printf("Error al eliminar semaforo.\n");
}
}
void mostarMensaje(char *quien, char *que) {
char mensaje[128];
time_t t=time(NULL);
sprintf(mensaje, "%s pid %u: %s %s",quien, getpid(), que, ctime(&t));
}
void barbero() {
while (1) {
P(CLIENTES);
Pb(MUTEX);
*clientes_espera--;
V(BARBEROS);
Vb(MUTEX);
mostarMensaje("barbaro","afeitando");
sleep(rand()%4+1);
mostarMensaje("barbaro","termina de afeitar");
}
}
void cliente() {
mostarMensaje("cliente","ha llegado");
Pb(MUTEX);
if (*clientes_espera<num_sillas) {
clientes_espera++;
V(CLIENTES);
Vb(MUTEX);
P(BARBEROS);
mostarMensaje("cliente","siendo afeitado");
} else {
Vb(MUTEX);
mostarMensaje("cliente","no atendido");
}
}
int main(int argc, char *argv[])
{
int mpk;
char msg[64];
if (argc<7 || argc>7) {
printf("mal pasados los argumentos");
exit(0);
} else {
if (strcmp("-b",argv[2])) {
num_barberos=atoi(argv[3]);
if(strcmp("-s",argv[4])) {
num_sillas=atoi(argv[5]);
num_clientes=atoi(argv[7]);
} else {
num_sillas=atoi(argv[7]);
num_clientes=atoi(argv[5]);
}
} else if (strcmp("-s",argv[2])) {
num_sillas=atoi(argv[3]);
if(strcmp("-b",argv[4])) {
num_barberos=atoi(argv[5]);
num_clientes=atoi(argv[7]);
} else {
num_barberos=atoi(argv[7]);
num_clientes=atoi(argv[5]);
}
} else {
num_clientes=atoi(argv[3]);
if(strcmp("-b",argv[4])) {
num_barberos=atoi(argv[5]);
num_sillas=atoi(argv[7]);
} else {
num_barberos=atoi(argv[7]);
num_sillas=atoi(argv[5]);
}
}
}
pid_barberos=(int *) malloc(sizeof(int)*num_barberos);
if((cespera=shmget(IPC_PRIVATE,sizeof(int)*1,0660))==-1) {
printf("Error en acceso memoria compartida.");
exit(-1);
}
clientes_espera=(int *) shmat(cespera, (char *) 0, 0);
*clientes_espera=0;
CLIENTES=inicia(0);
BARBEROS=inicia(1);
for(i=0;i<num_barberos; i++) {
switch(pid_barberos[i]=fork()) {
case -1: printf("error fork barbero nmero %d\n",i);exit(1);
case 0: barbero(); exit(0);
}
}
for(i=0;i<num_clientes; i++) {
switch(fork()) {
case -1: printf("eror fork clienet nmero %d\n",i); exit(1);
case 0: srand(getpid()); sleep(rand()%7+1); cliente(); exit(0);
}
}
for(i=0;i<num_clientes; i++) {
sprintf(msg, "termino el hijo %u\n", wait((int *) NULL));
write(STDOUT_FILENO, msg, strlen(msg));
}
for(i=0; i<num_barberos; i++) {
mpk=kill(pid_barberos[i],SIGKILL);
}
return EXIT_SUCCESS;
}