Laboratórios CES-33 - Diogo de Albuquerque Cassimiro

1)O problema do produtor consumidor

Um dos problemas clássicos de sistemas operacionais é o problema do fornecedor consumidor. Supõe-se uma pilha de itens onde processos fornecedores empilham itens e processos consumidores os retiram.
O problema se dá quando com a pilha cheia, um consumidor tira um elemento assim liberando a pilha para um fornecedor, contudo pode acontecer de dois fornecedores receberem notarem que a pilha não está cheia e tentarem incluir um item na pilha, contudo pode acontecer dos dois colocarem o item estourando a pilha, o inverso também pode causar problemas, quando a pilha está vazia, e um fornecedor deposita um item e mais de um fornecedor tenta remover este item.
Dentre as várias soluções para esse problema de corrida, temos o uso de pipes, como o próprio nome sugere, pipe é uma função que armazena em buffer as entradas que desejamos colocar fornece a saída em outro ponto que desejamos ler, exatamente como um cano(pipe). O pipe garante a solução do problema de corrida pois apenas uma instrução poderá utilizar o pipe por vez seja ela fornecedora ou consumidora.
Segue abaixo uma tentativa(infelizmente frustrada) de se implementar a solução para este problema com pipes, infelizmente os processos consumidores não estão obtendo os valores corretos e não consegui descobrir porque, talvez algum erro de raciocínio ou mesmo alguma pequena falha de implementação, portanto não recomendo que use o código abaixo para estudo, mas segue como curiosidade.
Os resultados não representavam qualquer valor , portando não foram colocados

Código Fonte

#include <stdio.h>
#include <stdlib.h>
 
#define WRITE 0
#define READ 1
#define PROD 3
#define CONS 5
 
  /****************************************/
 /*problema dos condutores e consumidores*/
/****************************************/
 
int i=0,producers=0, consumers=0;
 
void createproducer();
void createconsumer();
void consumer(int i,int fd[2]);
void producer(int i,int fd[2]);
 
void main()
{
    int fd[2];
    printf("ok");     
    pipe(fd);
    printf("aqui");    
    for(i=0;i<PROD;i++)//cria produtores
        createproducer();
    for(i=0;i<CONS;i++)    //cria consumidores
        createconsumer();
    wait();        //espera que os filhos terminem( no caso nunca)
}
 
void createproducer(int fd[2])
{
    producers++;
    printf("criado produtor %d\n",producers); 
    if (fork()==0)             //son, producer
        producer(i+1,fd);
    return;
}
 
void createconsumer(int fd[2])
{
    consumers++;
    printf("criado consumidor %d\n",consumers); 
    if (fork()==0)             //son, consumer
        consumer(i+1,fd);
    return;
}
 
void producer(int i,int fd[2]) 
{
    int item;
    sleep(10);
    srand(time(NULL));    
    while (1) 
    {
 
        sleep(5+rand()%5);    
        item = produce_item();
        close(fd[READ]);        //fecha a entrada de leitura
        write(fd[WRITE],&item,sizeof(int));
        printf ("O produtor %d produziu o item %d e pos na pilha\n",i,item);  
        close(fd[WRITE]);         //fecha a entrada de escrita    
 
    }
exit(0);  
}
void consumer(int i,int fd[2]) 
{
    srand(time(NULL));
    int item,bytesRead;
    while (1) 
    {    
        sleep(5+rand()%5);
        printf("aaaah");
        close(fd[WRITE]);                //fecha a entrada de escrita
        bytesRead = read(fd[READ],&item,sizeof(int));        
        printf ("O consumidor %d consumiu o item %d e %d bytes da pilha\n",i,item,bytesRead);  
        close(fd[READ]);                 //fecha a entrada de leitura    
    } 
exit(0);
}
 
int produce_item()
{
    return (int)rand()%10;
}

2)Jantar dos filósofos

O jantar dos filósofos é um problema clássico de comunicacão entre processos, neste se consideram cinco filósofos ao redor de uma mesa redonda, onde cada filósofo compartilha um garfo com outro filósofo a sua direita e a sua esquerda, contudo cada filósofo precisa de dois garfos para comer, o que se quer obter é um algoritmo eficiente para fazer com que os filósofos tentem obter os garfos sem que estes fiquem esperando infinitamente.

Para tanto fazemos uso de semáforos e mutex. Os semáforos são tipos especiais de inteiros que garantem que processos que os processos só acessem um por vez e também que podem fazer processos esperarem té que sejam atingidas certas condicoes. OS mutex são um tipo particular de semáforo que só tem os valores zero ou um.

Os semáforos funcionam da seguinte forma, quando um processo tenta diminuir um semáforo se este semáforo for maior que zero o processo continua, mas se o semáforo estiver em zero, o processo fica em espera até que o valor do semáforo aumente. Desta forma podesse controlar quando um processo deverá ou não esperar.

No caso utilizamos um mutex para garantir que quando se fosse analisar a disponibilidade de garfos na mesa nenhum outro filósofo pudesse intervir, isto é quando um filósofo checa os garfos, o mutex vai para zero, se outro filósofo tentar acessar os garfos ele tentará diminuir o mutex assim este outro filósofo entrará em estado de espera até que o mutex aumente para que ele o possa diminuir.

Os semáforos foram utilizados para fazer com que o processo do filósofo que estivesse querendo comer, esperasse até obter os gráficos.

Código Fonte

#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
 
#define N 5
#define LEFT          (i+N-1)%N
#define RIGHT         (i+1)%N
#define THINKING     0
#define HUNGRY         1
#define EATING        2
 
/************************/
/* jantar dos filósofos */
/************************/
 
//declaracoes
 
int state[N];             //array para saber o estado de cada filósofo
pthread_mutex_t mutex;     //exclusão mútua para regiões críticas
sem_t s[N];             // um semáforo por filósofo
int indexes[N];      //índice dos poetas
 
pthread_t phi[N];     //filósofos 
char* nomes[N] = {"Adrian","Boyle","Carl","Davion","Erand"}; // nomes dos filósosofos
//obs: temos que acrescentar mais nomes se aumentarmos N
void *saida;
 
void think(int);
void *philosopher(void *arg);
void take_forks(int);
void test(int);
void eat(int);
void put_forks(int);
 
int main()
{
int res,i;
srand(time(NULL));
 
    for(i=0;i<N;i++)
    {
        indexes[i]=i;
        state[i]=0;    
    }
    //inicializa mutex
    res = pthread_mutex_init(&mutex,NULL);
    if (res!=0) 
        { 
            perror("Mutex initialization failed");
            return 1;
        }
 
    //inicializa semáforos
    for( i=0;i<N;i++)
    {
        res = sem_init(&s[i], 0, 0);
        if (res!=0) 
        { 
            perror("Semaphore initialization failed");
            return 1;
        }
    }
 
    printf("Tem inicio o jantar dos filósofos:\n\n");
 
    //inicia threads
    for(i=0;i<N;i++)
    {
        res=pthread_create(&phi[i],NULL,philosopher,(void *) &indexes[i]);
        if (res!=0) 
        { 
            perror("Thread creation failed");
            printf("Não nasce %s \n",nomes[i]); 
            return 1;
        }
 
    }
    //espera a thread 1 terminar (a princípio nunca no caso)
    res=pthread_join(phi[0],saida);
    if (res!=0) 
    { 
        perror("Thread join failed");
        return 1;
    }
 
    //termina os semáforos
    for(i=0;i<N;i++)
    {
        sem_destroy(&s[i]);
    }
    //termina o mutex
    pthread_mutex_destroy(&mutex);
return 0;
}
 
void *philosopher (void *arg)
{
    int i = *(int *) arg; // identifica o filósofo
    printf("Nasce %s \n",nomes[i]);    
    while (1)
    {
        think(i);
        take_forks(i);
        eat(i);
        put_forks(i);
    }
pthread_exit(saida);
}
 
void take_forks(int i)
{
    pthread_mutex_lock(&mutex);         //entra na região crítica
    printf("%s esta faminto\n",nomes[i]);
    state[i]=HUNGRY;    //define o estado para faminto
    printf("%s tenta pegar garfos\n",nomes[i]);    
    test(i);         //tenta adquirir dois garfos 
    pthread_mutex_unlock(&mutex);        //sai da região crítica
    sem_wait(&s[i]);     // bloqueia se não conseguir os garfos
}
 
void put_forks(int i)
{
    pthread_mutex_lock(&mutex);         //entra na região crítica
    printf("%s para de comer e comeca a pensar\n",nomes[i]);        
    state[i]=THINKING;    //define o estado para pensando
    test(LEFT);        //verifica se o esquerdo pode comer agora
    test(RIGHT);         //verifica se o direito pode comer
    pthread_mutex_unlock(&mutex);        //sai da região crítica
}
 
void test(int i)
{
    if (state[i]==HUNGRY && state[LEFT]!=EATING && state[RIGHT]!=EATING) 
    {
        printf("%s consegue pegar garfos e comeca a comer\n",nomes[i]);            
        state[i]=EATING;
        sem_post(&s[i]);
    }    
}
 
void think(int i)
{
    printf("%s esta pensando\n",nomes[i]);
    sleep(rand()%10); //pensando
    printf("%s terminou de pensar\n",nomes[i]);
}
 
void eat(int i)
{
    printf("%s esta comendo\n",nomes[i]);
    sleep(rand()%10); //comendo
    printf("%s terminou de comer\n",nomes[i]);
}

Testes

Os resultados obtidos com esse código foram condizentes com o esperado. Obs: os filósofos foram nomeados com nomes que comecam em A,B,C,D,E para facilitar o reconhecimento dos mesmos em ordem alfabética na mesa:

Nasce Adrian
Adrian esta pensando
Nasce Boyle
Boyle esta pensando
Nasce Carl
Carl esta pensando
Nasce Davion
Davion esta pensando
Nasce Erand
Erand esta pensando
Boyle terminou de pensar
Boyle esta faminto
Boyle tenta pegar garfos
Boyle consegue pegar garfos e comeca a comer
Boyle esta comendo
Carl terminou de pensar
Carl esta faminto
Carl tenta pegar garfos
Erand terminou de pensar
Erand esta faminto
Erand tenta pegar garfos
Erand consegue pegar garfos e comeca a comer
Erand esta comendo
Adrian terminou de pensar
Adrian esta faminto
Adrian tenta pegar garfos
Davion terminou de pensar
Davion esta faminto
Davion tenta pegar garfos
Erand terminou de comer
Erand para de comer e comeca a pensar
Davion consegue pegar garfos e comeca a comer
Erand esta pensando
Davion esta comendo
Davion terminou de comer
Davion para de comer e comeca a pensar
Davion esta pensando
Davion terminou de pensar
Davion esta faminto
Davion tenta pegar garfos
Davion consegue pegar garfos e comeca a comer
Davion esta comendo
Davion terminou de comer
Davion para de comer e comeca a pensar
Davion esta pensando
Erand terminou de pensar
Erand esta faminto
Erand tenta pegar garfos
Erand consegue pegar garfos e comeca a comer
Erand esta comendo
Boyle terminou de comer
Boyle para de comer e comeca a pensar
Carl consegue pegar garfos e comeca a comer
Boyle esta pensando
Carl esta comendo
Carl terminou de comer
Carl para de comer e comeca a pensar
Carl esta pensando
Erand terminou de comer
Erand para de comer e comeca a pensar
Adrian consegue pegar garfos e comeca a comer
Erand esta pensando
Adrian esta comendo
Carl terminou de pensar
Carl esta faminto
Carl tenta pegar garfos
Carl consegue pegar garfos e comeca a comer
Carl esta comendo
Adrian terminou de comer
Adrian para de comer e comeca a pensar
Adrian esta pensando
Carl terminou de comer
Carl para de comer e comeca a pensar
Carl esta pensando
Davion terminou de pensar
Davion esta faminto
Davion tenta pegar garfos
Davion consegue pegar garfos e comeca a comer
Davion esta comendo
Erand terminou de pensar
Erand esta faminto
Erand tenta pegar garfos
Davion terminou de comer
Davion para de comer e comeca a pensar
Erand consegue pegar garfos e comeca a comer
Davion esta pensando
Erand esta comendo
Boyle terminou de pensar
Boyle esta faminto
Boyle tenta pegar garfos
Boyle consegue pegar garfos e comeca a comer
Boyle esta comendo

Percebe-se que em nenhum momento, filósofos adjacentes estão comendo e os filósofos não ficam infinitamente esperando para comer. É claro isto não quer dizer que o código está perfeitamente correto pois uma afirmacão destas iria requerer uma extensa bateria de testes mas os resultados até então indicam satisfatoriamente que o programa está correto.

3)O Problema da Barbearia

O problema da barbearia é semelhante ao problema dos filósofos com o diferencial de que o número de clientes da barbearia não é fixo, e a barbearia tem um limite para o número de clientes, assim a disponibilidade das cadeiras depende da chegada de clientes e do barbeiro os atender, sendo que estes passos devem ser isolados para evitar situações de corrida, desta forma é criado um semáforo para cliente e outro para para barbeiro e para evitar acesso simultâneo da fila de clientes é utilizado um multex. Uma das diferencas desse código também foi a necessidade de alocacão dinâmica para as já que o número de clientes é variável com o tempo, ao invés dos filósofos que são um número fixo de 5 filósofos. Segue o código do programa:

Código Fonte

#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
 
#define CHAIRS 5
 
  /******************************/
 /* enquanto isso na barbearia */
/******************************/
 
//declaracoes
 
pthread_mutex_t mutex;         //exclusão mútua para regiões críticas
sem_t costumers,barbers;     // um semáforo para cliente e outro para o barbeiro
int waiting=0;            //número de clientes esperando
 
pthread_t barbert,*costumert,costumercreatort;     //threads do barbeiro e dos clientes 
 
void *saida;
 
void *costumercreator(void *arg);
void *barber(void *arg);
void *costumer(void *arg);
void get_haircut(int );
void cut_hair();
 
int main()
{
 
int res,i;
srand(time(NULL));
 
printf("\nenquanto isso na barbearia:\n\n");
 
    //inicializa mutex
    res = pthread_mutex_init(&mutex,NULL);
    if (res!=0) 
        { 
            perror("Mutex initialization failed");
            return 1;
        }
 
    //inicializa semáforos
    res = sem_init(&costumers, 0, 0);
    if (res!=0) 
    { 
        perror("Semaphore initialization failed");
        return 1;
    }
 
    res = sem_init(&barbers, 0, 0);
    if (res!=0) 
    { 
        perror("Semaphore initialization failed");
        return 1;
    }
 
    //inicia threads
    res=pthread_create(&barbert,NULL,barber,NULL);
    if (res!=0) 
    { 
        perror("Thread creation failed"); 
        return 1;
    }
 
    res=pthread_create(&costumercreatort,NULL,costumercreator,NULL);
    if (res!=0) 
    { 
        perror("Thread creation failed"); 
        return 1;
    }
 
    //espera a thread barbeiro terminar (a princípio nunca no caso)
    res=pthread_join(barbert,saida);
    if (res!=0) 
    { 
        perror("Thread join failed");
        return 1;
    }
 
return 0;
}
 
void *barber (void *arg)
{
    printf("O barbeiro abre a barbearia \n");    
    while (1)
    {
        printf("O barbeiro dorme\n");
        sem_wait(&costumers);            //espera clientes durmindo
        pthread_mutex_lock(&mutex);         //entra na região crítica
        waiting = waiting -1 ; //diminui a lista de clientes em espera
        printf("O barbeiro acorda\n");        
        sem_post(&barbers);
        printf("O barbeiro está pronto para cortar cabelo\n");
        pthread_mutex_unlock(&mutex);        
        cut_hair();        //barbeiro corta cabelo do cliente
    }
    pthread_exit(saida);
}
 
void *costumercreator(void *arg) //funcao para criacao aleatoria de clientes
{
int *j,res,i=0;
    while (1)
    {
        j=(int *)malloc(sizeof(int));
        *j=i;
        costumert=(pthread_t *)malloc(sizeof(pthread_t));
        res=pthread_create(costumert,NULL,costumer,(void *) j);
        if (res!=0) 
        { 
            perror("Thread creation failed");
            pthread_exit(saida);
        }
        sleep(1+rand()%5);         
    i++;
    }
    pthread_exit(saida);
}
 
void *costumer (void *arg)
{
    int i = *(int *) arg;
    pthread_mutex_lock(&mutex);     //entra na região crítica
    printf("Chega o cliente %d e verifica se tem cadeiras vagas\n",i+1);    
    if(waiting < CHAIRS)
    {
        printf("Cliente %d acha cadeira vaga e senta\n",i+1);    
        waiting=waiting+1;                    //incrementa o número de clientes na espera
        printf("A barbearia está com %d cadeiras vagas\n",CHAIRS-waiting);
        sem_post(&costumers);            //acorda o barbeiro se for preciso para prestar o atendimento
        pthread_mutex_unlock(&mutex);        //
        sem_wait(&barbers);
        get_haircut(i);
    }
    else
    {
        printf("Cliente %d não acha cadeiras vagas e vai embora \n",i+1);
        pthread_mutex_unlock(&mutex);        //libera região crítica        
    }
    pthread_exit(saida);
}
 
void cut_hair()
{
    printf("O barbeiro corta o cabelo do cliente\n");     
    sleep(5);
}
 
void get_haircut(int i)
{
    printf("Cliente %d recebe corte de cabelo\n",i+1);     
    sleep(5);
}

Testes

Rodamos o programa diversas vezes buscando eventuais erros na ordem dos eventos, alguns erros foram encontrados e corrigidos, e no final não houveram erros aparentes. No final obtivemos como saida resultados como:

O barbeiro abre a barbearia
O barbeiro dorme
Chega o cliente 1 e verifica se tem cadeiras vagas
Cliente 1 acha cadeira vaga e senta
A barbearia está com 4 cadeiras vagas
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 1 recebe corte de cabelo
Chega o cliente 2 e verifica se tem cadeiras vagas
Cliente 2 acha cadeira vaga e senta
A barbearia está com 4 cadeiras vagas
Chega o cliente 3 e verifica se tem cadeiras vagas
O barbeiro dorme
Cliente 3 acha cadeira vaga e senta
A barbearia está com 3 cadeiras vagas
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 2 recebe corte de cabelo
Chega o cliente 4 e verifica se tem cadeiras vagas
Cliente 4 acha cadeira vaga e senta
A barbearia está com 3 cadeiras vagas
Chega o cliente 5 e verifica se tem cadeiras vagas
Cliente 5 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 3 recebe corte de cabelo
Chega o cliente 6 e verifica se tem cadeiras vagas
Cliente 6 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 4 recebe corte de cabelo
Chega o cliente 7 e verifica se tem cadeiras vagas
Cliente 7 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 5 recebe corte de cabelo
Chega o cliente 8 e verifica se tem cadeiras vagas
Cliente 8 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 6 recebe corte de cabelo
Chega o cliente 9 e verifica se tem cadeiras vagas
Cliente 9 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 7 recebe corte de cabelo
Chega o cliente 10 e verifica se tem cadeiras vagas
Cliente 10 acha cadeira vaga e senta
A barbearia está com 2 cadeiras vagas
Chega o cliente 11 e verifica se tem cadeiras vagas
Cliente 11 acha cadeira vaga e senta
A barbearia está com 1 cadeiras vagas
Chega o cliente 12 e verifica se tem cadeiras vagas
Cliente 12 acha cadeira vaga e senta
A barbearia está com 0 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 8 recebe corte de cabelo
Chega o cliente 13 e verifica se tem cadeiras vagas
Cliente 13 acha cadeira vaga e senta
A barbearia está com 0 cadeiras vagas
O barbeiro dorme
O barbeiro acorda
O barbeiro está pronto para cortar cabelo
O barbeiro corta o cabelo do cliente
Cliente 9 recebe corte de cabelo
Chega o cliente 14 e verifica se tem cadeiras vagas
Cliente 14 acha cadeira vaga e senta
A barbearia está com 0 cadeiras vagas
Chega o cliente 15 e verifica se tem cadeiras vagas
Cliente 15 não acha cadeiras vagas e vai embora

Repare que por diversas vezes o barbeiro entra no estado de durmir, mas no caso de haver um cliente ele é acordado no mesmo momento, os resultados foram condizentes com o esperado, não ficando mais clientes do que o possível na barbearia, nem tendo mais de um cliente cortando o cabelo simultaniamente, ou qualquer cliente saindo sem que a barberia estivesse cheia, ou o barbeiro parado com clientes na espera.

4)O Problema dos Leitores e Escritores

O problema se trata da gestão do acesso de um banco de dados por processos que desejam ler dados contidos nestes, e processos que desejam escrever dados no banco de dados. A diferenća principal dos problemas anteriores é que mais de um processo pode ler por vez o banco de dados, mas apenas um pode escrever no banco de dados. Poderíamos utilizar o sistema de alocacão dinâmica para gerar escritores e leitores aleatoriamente e de modo constante, contudo pelo modo que implementei os leitores e escritores não se encerram com o tempo, assim gerar de modo infinito leitores e escritores acabaria por gerar muitas threads e os leitores poderiam acabar por não deixar qualquer escritor entrar em momento algum no banco de dados pois haveriam muitos leitores acessando.

A diferenca principal do código é que se precisa fazer uma diferenciacao para o último que estava lendo e para o primeiro leitor que quer ler, pois o primeiro leitor é o que solicita o acesso para o banco de dados, se este conseguir todos os outros leitores o podem fazer, contudo é importante que só um leitor o soliscite caso contrário, cada leitor ficaria barrado até a solicitaćão de acesso de cada um ser recebida. O último leitor a deixar de ler tambem deve ser diferenciado pois só então deve ser liberado o acessso ao banco de dados tanto para novos leitores quanto para escritores. Note que se houverem escritores esperando estes serão os próximos a acessar o banco de dados já que foi o último leitor interassado em ler que liberou o acesso ao banco de dados.

Código Fonte

#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
 
#define ESCRITORES 2
 
  /*************************************/
 /* problema dos leitores e escritores*/
/*************************************/
 
//declaracoes
 
pthread_mutex_t mutex;         //exclusão mútua para região crítica rc
sem_t db;             // controla acesso a base de dados
int rc=0;            //número de processos lendo ou querendo ler
 
pthread_t writert[ESCRITORES],*readert, readercreatort;     //threads dos escritores e leitores 
 
void *saida;
 
void *readercreator(void *arg);
void *reader(void *arg);
void *writer(void *arg);
void read_data_base(int );
void use_data_read(int);
void think_up_data(int);
void write_data_base(int);
 
int main()
{
 
int res,i,indexes[ESCRITORES];
double tempo;
srand(time(NULL));
 
printf("\nproblema dos Leitores e Escritores:\n\n");
 
for (i=0;i<ESCRITORES;i++)
    indexes[i]=i;
 
    //inicializa mutex
    res = pthread_mutex_init(&mutex,NULL);
    if (res!=0) 
    { 
        perror("Mutex initialization failed");
        return 1;
    }
 
    //inicializa semáforos
    res = sem_init(&db, 0, 1);
    if (res!=0) 
    { 
        perror("Semaphore initialization failed");
        return 1;
    }
 
    //inicia threads
    for(i=0;i<ESCRITORES;i++)
    {
 
        res=pthread_create(&writert[i],NULL,writer,(void *) &indexes[i]);
        if (res!=0) 
        { 
            perror("Thread creation failed");
            return 1;
        }
 
    }
 
    res=pthread_create(&readercreatort,NULL,readercreator,NULL);    
    if (res!=0) 
    { 
        perror("Thread creation failed");
        return 1;
    }
 
    //espera a thread do primeiro escritor terminar (a princípio nunca no caso)
    res=pthread_join(writert[0],saida);
    if (res!=0) 
    { 
        perror("Thread join failed");
        return 1;
    }
 
return 0;
}
 
void *readercreator (void *arg)
{
int res, i=0, *j;
    while (i<5)
    {
        sleep(1+rand()%20);
        readert = (pthread_t *)malloc(sizeof(pthread_t));
        j= (int *)malloc(sizeof(int));
        *j=i;
        res=pthread_create(readert,NULL,reader,(void *) j);
            if (res!=0) 
            { 
                perror("Thread creation failed");
                pthread_exit(saida);
            }
    i=i+1;
    }
pthread_exit(saida);
}
 
void *reader (void *arg)
{
    int i = *(int *) arg;
    printf("Leitor %d acessa o sistema\n",i+1);    
    while (1)
    {
 
        pthread_mutex_lock(&mutex);         //entra na região crítica
        printf("Leitor %d entra na fila de leitores na posicao %d\n",i+1,rc+1);
        rc = rc+1;                 //aumenta o número de leitores
        if(rc==1) 
        {
            printf("Leitor %d entra como primeiro da fila e solicita acesso ao banco de dados so para leitores\n",i+1);    
            sem_wait(&db);            //se este é o primeiro leitor tenta acessar o a base de dados
            printf("Leitor %d acessa o banco de dados e restringe o acesso só para leitores\n",i+1);    
 
        }
 
        pthread_mutex_unlock(&mutex);         //libera acesso a região crítica
        read_data_base(i);            // lê o banco de dados
        pthread_mutex_lock(&mutex);         //entra na região crítica        
        printf("Leitor %d sai da fila de leitores\n",i+1);        
        rc=rc-1;
        if(rc==0)
        {
            printf("Leitor %d era o último leitor e libera acesso de leitores e escritores ao banco de dados\n",i+1);    
            sem_post(&db);         //se este é o último leitor libera o acesso ao banco de dados para leitores e escritores
        }        
 
        pthread_mutex_unlock(&mutex);        //libera acesso a região crítica, fila de leitores
        use_data_read(i);             //usa dados lidos, não requer acesso ao banco de dados
    }
 
}
 
void *writer (void *arg)
{
    int i = *(int *) arg;
    sleep(1+rand()%10); //tempo para chegada do escritor
    printf("Escritor %d acessa o sistema\n",i+1);
    while (1)
    {
        think_up_data(i);    //escritor pensa o que irá escrever, não requer acesso ao banco de dados
        printf("Escritor %d solicita acesso para escrever\n",i+1);
        sem_wait(&db);        //escritor solicita acesso exclusivo ao banco de dados
        printf("Escritor %d obtem acesso exclusivo ao banco de dados\n",i+1);
        write_data_base(i);    //escritor obtem acesso e escreve na banco de dados
        printf("Escritor %d libera acesso ao banco de dados\n",i+1);
        sem_post(&db);    
 
    }    
}
 
void read_data_base(int i)
{
    printf("Leitor %d está lendo banco de dados\n",i+1);     
    sleep(1+rand()%7);
    printf("Leitor %d terminou de ler banco de dados\n",i+1);            
}
 
void use_data_read(int i)
{
    printf("Leitor %d está usando dados lidos\n",i+1);     
    sleep(rand()%15);
    printf("Leitor %d terminou de usar dados lidos\n",i+1);            
}
 
void think_up_data(int i)
{
    printf("Escritor %d pensa o que irá escrever\n",i+1);
    sleep(rand()%10);
    printf("Escritor %d já sabe o que irá escrever\n",i+1);
}
 
void write_data_base(int i)
{
    printf("Escritor %d está escrevendo\n",i+1);
    sleep(5+rand()%10);
    printf("Escritor %d terminou de escrever\n",i+1);
}

Testes

Os testes realizados revelaram-se satisfatórios visto que nenhum, leitor acessava o banco de dados acessava o banco de dados enquanto um escritor estivesse acessando e vice-versa. Enquanto um leitor estivesse lendo o banco de dados, todos liam livremente o banco de dados como esperado, e no caso do escritor verficou-se que quando um tinha acesso ao banco de dados este era exclusivo como se queria. Os resultados a seguir exemplificam isto:
obs: repa que quando os leitores estão na fila de leitura não significa que eles estão esperando, eles podem ler na fila de leitura caso já tenham acesso.

Escritor 1 acessa o sistema
Escritor 1 pensa o que irá escrever
Escritor 1 já sabe o que irá escrever
Escritor 1 solicita acesso para escrever
Escritor 1 obtem acesso exclusivo ao banco de dados
Escritor 1 está escrevendo
Escritor 2 acessa o sistema
Escritor 2 pensa o que irá escrever
Escritor 2 já sabe o que irá escrever
Escritor 2 solicita acesso para escrever
Leitor 1 acessa o sistema
Leitor 1 entra na fila de leitores na posicao 1
Leitor 1 entra como primeiro da fila e solicita acesso ao banco de dados so para leitores
Escritor 1 terminou de escrever
Escritor 1 libera acesso ao banco de dados
Escritor 1 pensa o que irá escrever
Escritor 2 obtem acesso exclusivo ao banco de dados
Escritor 2 está escrevendo
Escritor 1 já sabe o que irá escrever
Escritor 1 solicita acesso para escrever
Leitor 2 acessa o sistema
Escritor 2 terminou de escrever
Escritor 2 libera acesso ao banco de dados
Escritor 2 pensa o que irá escrever
Leitor 1 acessa o banco de dados e restringe o acesso só para leitores
Leitor 1 está lendo banco de dados
Leitor 2 entra na fila de leitores na posicao 2
Leitor 2 está lendo banco de dados
Leitor 2 terminou de ler banco de dados
Leitor 2 sai da fila de leitores
Leitor 2 está usando dados lidos
Leitor 2 terminou de usar dados lidos
Leitor 2 entra na fila de leitores na posicao 2
Leitor 2 está lendo banco de dados
Escritor 2 já sabe o que irá escrever
Escritor 2 solicita acesso para escrever
Leitor 2 terminou de ler banco de dados
Leitor 2 sai da fila de leitores
Leitor 2 está usando dados lidos
Leitor 1 terminou de ler banco de dados
Leitor 1 sai da fila de leitores
Leitor 1 era o último leitor e libera acesso de leitores e escritores ao banco de dados
Leitor 1 está usando dados lidos
Escritor 1 obtem acesso exclusivo ao banco de dados
Escritor 1 está escrevendo
Leitor 3 acessa o sistema
Leitor 3 entra na fila de leitores na posicao 1
Leitor 3 entra como primeiro da fila e solicita acesso ao banco de dados so para leitores
Leitor 4 acessa o sistema
Leitor 5 acessa o sistema
Leitor 1 terminou de usar dados lidos
Escritor 1 terminou de escrever
Escritor 1 libera acesso ao banco de dados
Escritor 1 pensa o que irá escrever
Escritor 1 já sabe o que irá escrever
Escritor 1 solicita acesso para escrever
Escritor 1 obtem acesso exclusivo ao banco de dados
Escritor 1 está escrevendo
Leitor 2 terminou de usar dados lidos
Escritor 1 terminou de escrever
Escritor 1 libera acesso ao banco de dados
Escritor 1 pensa o que irá escrever
Leitor 3 acessa o banco de dados e restringe o acesso só para leitores
Leitor 3 está lendo banco de dados
Leitor 4 entra na fila de leitores na posicao 2
Leitor 4 está lendo banco de dados
Leitor 5 entra na fila de leitores na posicao 3
Leitor 5 está lendo banco de dados
Leitor 1 entra na fila de leitores na posicao 4
Leitor 1 está lendo banco de dados
Leitor 2 entra na fila de leitores na posicao 5
Leitor 2 está lendo banco de dados
Leitor 4 terminou de ler banco de dados
Leitor 4 sai da fila de leitores
Leitor 4 está usando dados lidos
Leitor 5 terminou de ler banco de dados
Leitor 5 sai da fila de leitores
Leitor 5 está usando dados lidos
Leitor 2 terminou de ler banco de dados
Leitor 2 sai da fila de leitores
Leitor 2 está usando dados lidos
Leitor 2 terminou de usar dados lidos
Leitor 2 entra na fila de leitores na posicao 3
Leitor 2 está lendo banco de dados
Leitor 3 terminou de ler banco de dados
Leitor 3 sai da fila de leitores
Leitor 3 está usando dados lidos
Leitor 2 terminou de ler banco de dados
Leitor 2 sai da fila de leitores
Leitor 2 está usando dados lidos
Leitor 1 terminou de ler banco de dados
Leitor 1 sai da fila de leitores
Leitor 1 era o último leitor e libera acesso de leitores e escritores ao banco de dados
Leitor 1 está usando dados lidos
Escritor 2 obtem acesso exclusivo ao banco de dados
Escritor 2 está escrevendo
Leitor 5 terminou de usar dados lidos
Leitor 5 entra na fila de leitores na posicao 1
Leitor 5 entra como primeiro da fila e solicita acesso ao banco de dados so para leitores
Escritor 1 já sabe o que irá escrever
Escritor 1 solicita acesso para escrever
Leitor 2 terminou de usar dados lidos
Leitor 4 terminou de usar dados lidos
Leitor 1 terminou de usar dados lidos
Leitor 3 terminou de usar dados lidos
Escritor 2 terminou de escrever
Escritor 2 libera acesso ao banco de dados

5)O Problema do Banheiro Unisex - primeira questão da prova

O problema consta da organizaćão do uso de banheiros entre homens e mulheres, sendo que os homens não podem usar os banheiros quando há mulheres e vice-versa, assim o primeiro dos sexos que chegar ao banheiro terá acesso exclusivo até que o último deste sexo saia do banheiro, podendo assim o outro sexo utilizar o banheiro.

Este problema contém semelhancas com dois problemas anteriores, o problema da Barbearia e dos leitores e escritores. o problema da barbearia tem é semelhante a este na medida que o número de usuários do banheiro não é fixo assim como na barbearia não o era, com a diferenca que desta vez temos dois grupos de usuário que nao sao fixos, desta forma, precisamos realizar a alocacao dinamica dos homens e das mulheres que vao chegando aleatoriamente ao banheiro. O problema dos leitores e escritores, trata de modo semelhante o modo como os leitores usam o banco de dados ao modo como queremos que cada sexo possa usar o banco de dados, contudo neste problema, temos dois grupos que querem acesso semelhante ao dos leitores no problema anterior, assim precisamos criar duas filas uma para as mulheres e para os homens, perceba que se utilizarmos então um único mutex, ao bloquearmos a fila dos homens quando um desejar entrar ou sair do banheiro, estaremos também bloqueando a fila das mulheres, assim para evitar um deadlock, é preciso criar dois mutex cada um para o controle do acesso a região crítica, assim a chegada de uma mulher não bloquearia um homem e vice-versa. O controle de quem acessa o banheiro é feito com um semáforo levando em consideracão ,de modo semelhante ao problema anterior, o primeiro membro do grupo a tentar entrar e o último a sair. Segue o código:

Código Fonte

#include <stdio.h>
#include <pthread.h>
#include <sys/wait.h>
#include <semaphore.h>
#include <string.h>
#include <time.h>
 
  /*************************************/
 /* problema do banheiro unisex          */
/*************************************/
 
//declaracoes
 
pthread_mutex_t mutex,mutex2;         // exclusão mútua para regiões críticas
sem_t bt;             // controla acesso ao banheiro
int numman=0;            // número de homens no banheiro 
int numwoman=0;            // número de mulheres no banheiro
 
pthread_t *mant, *womant,mancreatort,womancreatort;     //threads dos homens e mulheres
 
void *saida;
 
void *man(void *arg);
void *mancreator(void *arg);
void *woman(void *arg);
void *womancreator(void *arg);
void homem_usa_banheiro(int);
void mulher_usa_banheiro(int);
 
int main()
{
 
int res,i;
double tempo;
srand(time(NULL));
 
printf("\nproblema do banheiro unisex:\n\n");
 
    //inicializa mutex
    res = pthread_mutex_init(&mutex,NULL);
    if (res!=0) 
    { 
        perror("Mutex initialization failed");
        return 1;
    }
 
    res = pthread_mutex_init(&mutex2,NULL);
    if (res!=0) 
    { 
        perror("Mutex initialization failed");
        return 1;
    }
 
    //inicializa semáforos
    res = sem_init(&bt, 0, 1);
    if (res!=0) 
    { 
        perror("Semaphore initialization failed");
        return 1;
    }
 
    //inicia threads
    res=pthread_create(&mancreatort,NULL,mancreator, NULL);    
    if (res!=0) 
    { 
        perror("Thread creation failed");
        return 1;
    }
 
    res=pthread_create(&womancreatort,NULL,womancreator,NULL);    
    if (res!=0) 
    { 
        perror("Thread creation failed");
        return 1;
    }
 
    //espera a thread do criador de homens terminar (a princípio nunca no caso)
    res=pthread_join(mancreatort,saida);
    if (res!=0) 
    { 
        perror("Thread join failed");
        return 1;
    }
 
return 0;
}
 
void *mancreator (void *arg)
{
int res,i=0, *j;
    while (1)
    {
        sleep(1+rand()%5);
        mant = (pthread_t *)malloc(sizeof(pthread_t));
        j= (int *)malloc(sizeof(int));
        *j=i;
        res=pthread_create(mant,NULL,man,(void *) j);
            if (res!=0) 
            { 
                perror("Thread creation failed");
                pthread_exit(saida);
            }
    i=i+1;
    }
pthread_exit(saida);
}
 
void *womancreator (void *arg)
{
int res,i=0, *j;
    while (1)
    {
        sleep(1+rand()%7);
        womant = (pthread_t *)malloc(sizeof(pthread_t));
        j= (int *)malloc(sizeof(int));
        *j=i;
        res=pthread_create(womant,NULL,woman,(void *) j);
            if (res!=0) 
            { 
                perror("Thread creation failed");
                pthread_exit(saida);
            }
    i=i+1;
    }
pthread_exit(saida);
}
 
void *man (void *arg)
{
    int i = *(int *) arg;
    printf("Homem %d quer usar o banheiro\n",i+1);    
 
    pthread_mutex_lock(&mutex);         //entra na região crítica
    printf("Homem %d entra na fila de homens na posicao %d\n",i+1,numman+1);
    numman = numman+1;                 //aumenta o número de homens
 
    if(numman==1) 
    {
        printf("Homem %d entra como primeiro da fila e solicita acesso ao banheiro so para homens\n",i+1);    
        sem_wait(&bt);            //se este é o primeiro homem ele espera o banehiro estar vazio
        printf("Homem %d entra no banheiro e restringe o acesso só para homens\n",i+1);    
    }
 
    pthread_mutex_unlock(&mutex);         //libera acesso a região crítica
    homem_usa_banheiro(i);            // homem usa o banheiro
    pthread_mutex_lock(&mutex);         //entra na região crítica        
    printf("Homem %d sai do banheiro\n",i+1);        
    numman=numman-1;
    if(numman==0)
    {
        printf("Homem %d era o último no banheiro e libera acesso do banheiro a homens e mulheres\n",i+1);    
        sem_post(&bt);         //se este é o último homem ele libera o acesso do banheiro
    }        
 
    pthread_mutex_unlock(&mutex);        //libera acesso a região crítica, fila numero de homens e mulheres no banheiro
pthread_exit(saida);
}
 
void *woman (void *arg)
{
    int i = *(int *) arg;
    printf("Mulher %d quer usar o banheiro\n",i+1);    
 
    pthread_mutex_lock(&mutex2);         //entra na região crítica
    printf("Mulher %d entra na fila de mulheres na posicao %d\n",i+1,numwoman+1);
    numwoman = numwoman+1;                 //aumenta o número de homens
    if(numwoman==1) 
    {
        printf("Mulher %d entra como primeira da fila e solicita acesso ao banheiro so para mulheres\n",i+1);    
        sem_wait(&bt);            //se este é a primeira mulher ela espera o banheiro estar vazio
        printf("Mulher %d entra no banheiro e restringe o acesso só para mulheres\n",i+1);    
    }
 
    pthread_mutex_unlock(&mutex2);         //libera acesso a região crítica
    mulher_usa_banheiro(i);        // mulher usa o banheiro
    pthread_mutex_lock(&mutex2);         //entra na região crítica        
    printf("Mulher %d sai do banheiro\n",i+1);        
    numwoman=numwoman-1;
    if(numwoman==0)
    {
        printf("Mulher %d era o último no banheiro e libera acesso do banheiro a homens e mulheres\n",i+1);    
        sem_post(&bt);         //se esta é a última mulher ela libera o acesso do banheiro
    }        
 
    pthread_mutex_unlock(&mutex2);        //libera acesso a região crítica, fila numero de homens e mulheres no banheiro
pthread_exit(saida);
}
 
void mulher_usa_banheiro(int i)
{
    printf("Mulher %d está usando o banheiro\n",i+1);     
    sleep(2+rand()%5);
    printf("Mulher %d terminou de usar o banheiro\n",i+1);            
}
 
void homem_usa_banheiro(int i)
{
    printf("Homem %d está usando o banheiro\n",i+1);     
    sleep(1+rand()%5);
    printf("Homem %d terminou de usar o banheiro\n",i+1);            
}

Testes

Os testes corroboraram com as idéias apresentadas acima, fazendo com que o programa apresentasse os resultados esperados, ficando inclusive bem parecido com o problema dos Escritores e Leitores. Um erro encontrado nos resultados deste programa havia sido gerado pela troca de um dos nomes Homem por Mulher dando a falsa impressão de mal funcionamento do programa, mas o erro foi facilmente corrigido. Segue um exemplo dos resultados encontrados:

obs: Pessoa x quer usar o banheiro significa que chegou uma nova pessoa com a intencão de usar o banheiro.

Homem 1 quer usar o banheiro
Homem 1 entra na fila de homens na posicao 1
Homem 1 entra como primeiro da fila e solicita acesso ao banheiro so para homens
Homem 1 entra no banheiro e restringe o acesso só para homens
Homem 1 está usando o banheiro
Mulher 1 quer usar o banheiro
Mulher 1 entra na fila de mulheres na posicao 1
Mulher 1 entra como primeira da fila e solicita acesso ao banheiro so para mulheres
Homem 1 terminou de usar o banheiro
Homem 1 sai do banheiro
Homem 1 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Mulher 1 entra no banheiro e restringe o acesso só para mulheres
Mulher 1 está usando o banheiro
Homem 2 quer usar o banheiro
Homem 2 entra na fila de homens na posicao 1
Homem 2 entra como primeiro da fila e solicita acesso ao banheiro so para homens
Mulher 2 quer usar o banheiro
Mulher 2 entra na fila de mulheres na posicao 2
Mulher 2 está usando o banheiro
Homem 3 quer usar o banheiro
Mulher 1 terminou de usar o banheiro
Mulher 1 sai do banheiro
Mulher 2 terminou de usar o banheiro
Mulher 2 sai do banheiro
Mulher 2 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Homem 2 entra no banheiro e restringe o acesso só para homens
Homem 2 está usando o banheiro
Homem 3 entra na fila de homens na posicao 2
Homem 3 está usando o banheiro
Homem 4 quer usar o banheiro
Homem 4 entra na fila de homens na posicao 3
Homem 4 está usando o banheiro
Homem 3 terminou de usar o banheiro
Homem 3 sai do banheiro
Mulher 3 quer usar o banheiro
Mulher 3 entra na fila de mulheres na posicao 1
Mulher 3 entra como primeira da fila e solicita acesso ao banheiro so para mulheres
Homem 2 terminou de usar o banheiro
Homem 2 sai do banheiro
Homem 4 terminou de usar o banheiro
Homem 4 sai do banheiro
Homem 4 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Mulher 3 entra no banheiro e restringe o acesso só para mulheres
Mulher 3 está usando o banheiro
Homem 5 quer usar o banheiro
Homem 5 entra na fila de homens na posicao 1
Homem 5 entra como primeiro da fila e solicita acesso ao banheiro so para homens
Mulher 4 quer usar o banheiro
Mulher 4 entra na fila de mulheres na posicao 2
Mulher 4 está usando o banheiro
Mulher 3 terminou de usar o banheiro
Mulher 3 sai do banheiro
Mulher 4 terminou de usar o banheiro
Mulher 4 sai do banheiro
Mulher 4 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Homem 5 entra no banheiro e restringe o acesso só para homens
Homem 5 está usando o banheiro
Homem 6 quer usar o banheiro
Homem 6 entra na fila de homens na posicao 2
Homem 6 está usando o banheiro
Mulher 5 quer usar o banheiro
Mulher 5 entra na fila de mulheres na posicao 1
Mulher 5 entra como primeira da fila e solicita acesso ao banheiro so para mulheres
Homem 5 terminou de usar o banheiro
Homem 5 sai do banheiro
Homem 7 quer usar o banheiro
Homem 7 entra na fila de homens na posicao 2
Homem 7 está usando o banheiro
Homem 8 quer usar o banheiro
Homem 8 entra na fila de homens na posicao 3
Homem 8 está usando o banheiro
Homem 7 terminou de usar o banheiro
Homem 7 sai do banheiro
Homem 6 terminou de usar o banheiro
Homem 6 sai do banheiro
Homem 9 quer usar o banheiro
Homem 9 entra na fila de homens na posicao 2
Homem 9 está usando o banheiro
Homem 10 quer usar o banheiro
Homem 10 entra na fila de homens na posicao 3
Homem 10 está usando o banheiro
Mulher 6 quer usar o banheiro
Homem 8 terminou de usar o banheiro
Homem 8 sai do banheiro
Homem 11 quer usar o banheiro
Homem 11 entra na fila de homens na posicao 3
Homem 11 está usando o banheiro
Homem 9 terminou de usar o banheiro
Homem 9 sai do banheiro
Homem 11 terminou de usar o banheiro
Homem 11 sai do banheiro
Homem 10 terminou de usar o banheiro
Homem 10 sai do banheiro
Homem 10 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Mulher 5 entra no banheiro e restringe o acesso só para mulheres
Mulher 5 está usando o banheiro
Homem 12 quer usar o banheiro
Homem 12 entra na fila de homens na posicao 1
Homem 12 entra como primeiro da fila e solicita acesso ao banheiro so para homens
Mulher 6 entra na fila de mulheres na posicao 2
Mulher 6 está usando o banheiro
Homem 13 quer usar o banheiro
Mulher 7 quer usar o banheiro
Mulher 7 entra na fila de mulheres na posicao 3
Mulher 7 está usando o banheiro
Mulher 5 terminou de usar o banheiro
Mulher 5 sai do banheiro
Homem 14 quer usar o banheiro
Mulher 6 terminou de usar o banheiro
Mulher 6 sai do banheiro
Homem 15 quer usar o banheiro
Homem 16 quer usar o banheiro
Mulher 7 terminou de usar o banheiro
Mulher 7 sai do banheiro
Mulher 7 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Homem 12 entra no banheiro e restringe o acesso só para homens
Homem 12 está usando o banheiro
Homem 13 entra na fila de homens na posicao 2
Homem 13 está usando o banheiro
Homem 14 entra na fila de homens na posicao 3
Homem 14 está usando o banheiro
Homem 15 entra na fila de homens na posicao 4
Homem 15 está usando o banheiro
Homem 16 entra na fila de homens na posicao 5
Homem 16 está usando o banheiro
Mulher 8 quer usar o banheiro
Mulher 8 entra na fila de mulheres na posicao 1
Mulher 8 entra como primeira da fila e solicita acesso ao banheiro so para mulheres
Homem 16 terminou de usar o banheiro
Homem 16 sai do banheiro
Homem 12 terminou de usar o banheiro
Homem 12 sai do banheiro
Homem 14 terminou de usar o banheiro
Homem 14 sai do banheiro
Homem 17 quer usar o banheiro
Homem 17 entra na fila de homens na posicao 3
Homem 17 está usando o banheiro
Mulher 9 quer usar o banheiro
Homem 17 terminou de usar o banheiro
Homem 17 sai do banheiro
Homem 18 quer usar o banheiro
Homem 18 entra na fila de homens na posicao 3
Homem 18 está usando o banheiro
Homem 13 terminou de usar o banheiro
Homem 13 sai do banheiro
Homem 15 terminou de usar o banheiro
Homem 15 sai do banheiro
Mulher 10 quer usar o banheiro
Mulher 11 quer usar o banheiro
Homem 18 terminou de usar o banheiro
Homem 18 sai do banheiro
Homem 18 era o último no banheiro e libera acesso do banheiro a homens e mulheres
Mulher 8 entra no banheiro e restringe o acesso só para mulheres
Mulher 8 está usando o banheiro
Mulher 9 entra na fila de mulheres na posicao 2
Mulher 9 está usando o banheiro
Mulher 10 entra na fila de mulheres na posicao 3
Mulher 10 está usando o banheiro
Mulher 11 entra na fila de mulheres na posicao 4
Mulher 11 está usando o banheiro
Mulher 12 quer usar o banheiro
Mulher 12 entra na fila de mulheres na posicao 5
Mulher 12 está usando o banheiro
Homem 19 quer usar o banheiro
Homem 19 entra na fila de homens na posicao 1
Homem 19 entra como primeiro da fila e solicita acesso ao banheiro so para homens

Conclusões

Houveram grandes dificuldades em se interpretar as fontes bibliográficas no que se refere aos pipes, e mais dificuldades apareceram no momento de se orientar este conceito a solucão da questão o que refletiu no fracasso da realizacão do programa, as fontes bibliográficas eram muito compactas e a internet se revelou razoavelmente pobre com relacao a este assunto, talvez se tivesse buscado o conteúdo em um livro, o que não fiz, o resultado teria sido mais frutífero. Quanto aos outros programas devido a boa compreensão do conceito de semáforo e mutex considero que a implementacão foi interessante, e tomou um tempo adequado, passado alguns primeiros momentos de adaptacão ao que era pedido a programacão fluiu naturalmente. Considero que os conceitos foram bem entendidos e bem aplicados tendo como resultados saídas razoáveis nos programas implementados, é claro, excluindo o primeiro programa(utilizando pipes) no qual considerei meu desempenho não satisfatório.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License