sexta-feira, 8 de maio de 2009

Leitores e Escritores

O problema dos Leitores e Escritores é um dos mais conhecidos sobre Programação Concorrente. Este problema considera a existência de vários processos que tentam acessar a uma área de memória compartilhada, uns para ler, outros para escrever. O que se pretende é que um leitor e um escritor não colidam na sua atividade para que não se corra o risco de um ir ler o que outro ainda não acabou de escrever, ou de um escritor ir escrever sobre dados ainda não lidos pelo processo leitor.

No entanto, não parece haver impedimento algum para que, pelo menos os leitores, não possam aceder em simultâneo a referida área de memória compartilhada, bastando para tal que, um processo que pretenda ler, se certifique da presença de algum outro leitor ou da ausência de escritores.

O que não podemos permitir é que mais do que um escritor tenha acesso simultâneo. Isto poderia conduzir a uma alteração indevida do valor compartilhado.

Surge, então, um novo cenário em que vários leitores podem estar em simultâneo na seção crítica, enquanto que não se pode permitir a entrada a mais do que um escritor de cada vez, bem como a permanência simultânea de processos de tipos distintos (um leitor e um escritor, por exemplo). Variações a este caso, são a concessão de prioridade a leitores ou a escritores. Isto vem evitar que os leitores, por exemplo, ocupem de tal forma a seção compartilhada que não deixem espaço para que os escritores lá possam entrar.

O que é importante referir após a apresentação destes exemplos é que, além de termos de recorrer aos semáforos para controlar o acesso dos vários processos a memória compartilhada, temos também de garantir, nas várias versões apresentadas, uma exclusão mútua as variáveis auxiliares necessárias para o controle de entrada e saída.

Bibliografia: http://www.jr.eti.br

O trecho apresentado a seguir consiste em uma solu
ção para uma versão simplificada do problema. Considerei que existiam 20 leitores e um escritor que desejam acessar a base de dados. Os tempos de leitura e escrita selecionados (vide começo do programa) encaminham o problema para a seguinte situação: o escritor entra antes dos leitores e lá fica durante o tempo de escrita; os leitores entram a seguir e não ocorre liberação para o escritor acessar novamente, já que ele não tem qualquer tipo de prioridade sobre os leitores. O programa está mostrado logo abaixo. Logo depois, um screenshot do funcionamento do programa está exibido para comprovar o que foi dito anteriormente.


#include<semaphore.h>
#include<pthread.h>

#include<math.h>
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

#define NUMBER_READERS 20
#define TRUE 1
#define FALSE 0
#define READ_TIME 1
#define WRITE_TIME 3


pthread_mutex_t mutex;

pthread_mutex_t db;
int
rc = 0;

void
read_data_base(int i){

printf("There are %d readers in the database.\n", i);
}


void
write_data_base(){
printf("There is a writer in the database.\n");
}


void
reader(void) {
while
(TRUE) {
pthread_mutex_lock(&mutex);

rc++;
if
(rc == 1) pthread_mutex_lock(&db);

pthread_mutex_unlock(&mutex);
read_data_base(rc);
sleep(READ_TIME);

pthread_mutex_lock(&mutex);
rc--;
if
(rc == 0) pthread_mutex_unlock(&db);

pthread_mutex_unlock(&mutex);
}
}


void
writer(void) {
while
(TRUE) {

pthread_mutex_lock(&db);
write_data_base();
sleep(WRITE_TIME);
pthread_mutex_unlock(&db);
}
}


void
* call_writer(void* arg){
writer();
}


void
* call_reader(void* arg){
reader();
}


int
main() {

int
i;

pthread_mutex_init(&mutex, NULL);
pthread_mutex_init(&db, NULL);

pthread_t mr_writer;
pthread_create(&mr_writer, NULL, call_writer, NULL);

pthread_t readers[NUMBER_READERS];
for
(i=0; i<NUMBER_READERS; i++) {

pthread_create(&readers[i], NULL, call_reader, (void*) i);

sleep(READ_TIME);
}


return
0;
}

Nenhum comentário:

Postar um comentário