Produtor e Consumidor

INTRODUÇÃO

O problema do produtor e consumidor (também conhecido como problema do buffer limitado) tata-se de processos de dois tipo, produtor e consumidor, que comportilham um buffer comum e de tamanho fixo.
O consumidor tem a função de por informação dentro do buffer. O consumidor trata de retirar dados do buffer.
O problema ocorre quando um produtor tenta colocar um novo item no buffer, mas ele já está cheio. Assim, a solução é adormecer o produtor e só despertá-lo quando algum consumidor remover um ou mais itens. Da mesma forma, se um consumidor tentar remoer um item do buffer e perceber que o mesmo está vazio, ele dormirá até que qualquer produtor ponha algo no buffer e o desperte.

Para garantir a que apenas um processo vá atuar na região crítica (buffer) é necessário assegurar a exclusividade da atuação de colocar e retirar informação dela.

IMPLEMENTAÇÃO

Utilizando pipes e processos, implementou-se o problema do produtor e consumidor.

/* ***********************************************************************
Implementação da solução do problema produtor e consumidor
utilizando pipes e processos
 
O programa recebe 2 parametro:
 - primeiro corresponde ao número de produres para gerar
 - segundo corresponde ao número de consumidores para gerar 
 
 Tiago Porto, Maio 2009
 
************************************************************************** */
 
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
 
#define FALSE 0
#define TRUE 1
#define PRODUCER 0
#define CONSUMER 1
#define NOTHING 2
#define READ 0
#define WRITE 1
 
main(int argc, char* argv[]) {
    int fd1[2], n_producer, n_consumer, max_producer, max_consumer, to_be, pid=-1;
    char message[4];
    max_producer=atoi(argv[1]);
    max_consumer=atoi(argv[2]);
 
     /* Criando a pipe */
     pipe(fd1);
 
    /* Criando os processos filhos que serão produtores */
    if(pid!=0){
        for(n_producer = 0; n_producer<max_producer ; n_producer++){
            to_be=PRODUCER;
            if(pid!=0) pid = fork();
            else break;
        }    
    }
 
    /* Criando os processos filhos que serão consumidores */
    if(pid!=0){
        for(n_consumer = 0 ; n_consumer<max_consumer; n_consumer++){
            to_be=CONSUMER;
            if(pid!=0) pid = fork();
            else break;
        }
    }
 
    /* O processo pai não é nem produtor nem consumidor*/
    if(pid!=0) to_be=NOTHING;
 
    /* Se o processor for produtor */
    if(to_be==PRODUCER){
        sleep(2);
        close(fd1[READ]);
        sprintf(message, "%d", n_producer);
        write (fd1[WRITE], message, 2);
        close(fd1[WRITE]);
    }
 
    /* Se o processor for consumidor */
    if(to_be==CONSUMER){
        close(fd1[WRITE]);
        read (fd1[READ], message, 2);
        printf("Consumidor %d: %s\n", n_consumer, message);
        close(fd1[READ]);
    }
 
    if(pid!=0){
        while(1);
    }
}

TESTES

Teste 1: 2 produtores e 1 consumidor
Teste 2: 2 produtores e 4 consumidores
Teste 3: 4 produtores e 2 consumidores

Teste grande
http://ces33.wikidot.com/tiagoporto:produtor-e-consumidor-teste

$ ./produtor_e_consumidor 2 1
Consumidor 1: 1

$ ./produtor_e_consumidor 2 4
Consumidor 1: 1
Consumidor 2: 2

$ ./produtor_e_consumidor 5 2
Consumidor 1: 1
Consumidor 2: 2

Note que tanto o teste 1 quanto o teste 3 tem threads que são bloqueadas.

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