O Produtor e o Consumidor

Este artigo tem por finalidade apresentar um problema clássico em sistemas operacionais, a relação "o produtor e o consumidor", que visa por em prática a gerência de processos concorrentes em um sistema operacional. Problema: um processo escreve em um buffer limitado, enquanto outro lê e limpa o mesmo, preservando a integridade dos dados.

[ Hits: 87.930 ]

Por: Ricardo Bocchi em 27/01/2010 | Blog: http://ricardobocchi.blogspot.com/


Lógica e estruturação da solução - o consumidor



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.

Página anterior     Próxima página

Páginas do artigo
   1. O problema, uma breve introdução
   2. A solução, uma breve introdução
   3. Lógica e estruturação da solução - o produtor
   4. Lógica e estruturação da solução - o consumidor
   5. Código comentado na íntegra
   6. Compilação e execução
Outros artigos deste autor
Nenhum artigo encontrado.
Leitura recomendada

Estudando recursividade direta e indireta

Instalando Facebook Folly através do Conan

lib cURL - Trabalhe com URLs em C

Algum humor e C++ Design Patterns (parte 2)

Android NDK: Desmistificando o acesso a códigos nativos em C

  
Comentários
[1] Comentário enviado por pink em 29/01/2010 - 12:51h

Ótimo, meus parabéns.... sem comentários....
Aguardo pelo próximo artigo....

[2] Comentário enviado por saitam em 15/05/2010 - 16:54h

Ótimo artigo bem didático. Parabéns
Aguardo pelo próximo artigo [2]

[3] Comentário enviado por Claudinei_Jr em 03/04/2013 - 18:06h

Ótimo Artigo, super didático!
Parabéns!
Contribuiu muito com minhas pesquisas sobre o assunto!!!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts