O consumidor:
O consumidor deve fazer as mesmas verificações que faz o produtor, mas ao invés de escrever no buffer, ele deve ler e limpar o buffer.
/* Semáforo para definir status do consumidor - Dormindo ou acordado */
pthread_mutex_lock(&mutex_status_buff);
/* Se buffer ocupado for igual a zero espera até produtor avisar que tem produção no buffer */
if(buff_full == 0){
if (status_processamento == ACABADO && buff_empty == 8){
printf("\n[Consumidor diz:] Por hora acabou meu consumo, vou embora. Até..!!\n");
return;
}
printf("\n[Consumidor diz:] Vou dormir enquanto não tem consumo!!\n");
status_consome = DORMINDO;
pthread_cond_wait(&status_consumidor, &mutex_status_buff); /* Entra em modo de espera até receber sinal */
status_consome = ACORDADO; /* Muda status para ACORDADO e sai da espera */
printf("\n[Consumidor diz:] Nova produção chegando, vou consumir!!\n");
}
pthread_mutex_unlock(&mutex_status_buff);
Em um loop infinito, ele começa verificando se há alguma posição do buffer ocupada, se não houver entra em estado de espera, até que seja chamado pelo produtor. Também neste momento faz a verificação do estado de processamento do produtor, pois, se não houver produção e não for o fim da execução, ele entrará em modo de espera eterna.
pthread_mutex_lock(&mutex);
/* Pega posição da fila*/
c = getFila(&fila_leitura_inicio, &fila_leitura_fim);
if (c != ' ' || c != -1){
printf("\n\n[Consumidor diz:] Pid [%d] | Tid [%u] | Posição [%d] | %s [%c]\n",getpid(), (unsigned int)pthread_self(), c, (char*)texto, bufferLimitado[c]);
bufferLimitado[c] = ' ';/* Limpa buffer após leitura */
buff_empty++; /* Incrementa buffer livre */
buff_full--; /* Decrementa buffer ocupado */
/* Manda posição do buffer livre para fila */
setFila(c, &fila_escrita_inicio, &fila_escrita_fim);
/* Semáforo para verificação do status do produtor - Dormindo ou acordado */
pthread_mutex_lock(&mutex_status_buff);
if(status_produz == DORMINDO){/* Se estiver dormindo manda sinal para avisar que tem buffer livre */
printf("\n[Consumidor diz:] O produtor está dormindo, vou tocar a campainha, pois tem buffer livre!!\n");
sleep(rand() % 4);
pthread_cond_signal(&status_produtor);
}
/* Libera semáforo */
pthread_mutex_unlock(&mutex_status_buff);
Quando a condição for verdadeira, e houver posições prontas para a leitura, bloqueia o buffer (exclusão mútua) para poder ler e limpar. Retira posição da fila de leitura e adiciona posição na fila de escrita. Depois de ler, mostrar e limpar o buffer, ele incrementa a variável que controla os espaços livres e decrementa a variável que controla os espaços ocupados. Antes de terminar, verifica se produtor está em modo de espera, se estiver faz a chamada avisando que há produção no buffer, então começa a verificação novamente, até que não haja mais produção.