O problema de leitores e escritores é um problema clássico da teoria da computação , que permite modelar o acesso a bancos de dados .
Foi afirmado desta forma por Edsger Dijkstra , que também está na origem do problema do jantar dos filósofos (problema relacionado em particular com a ordenação dos processos).
Suponha que um banco de dados tenha leitores e gravadores, e os leitores e gravadores desse banco de dados precisem ser programados.
As restrições são as seguintes:
É muito simples colocar o editor em espera enquanto ainda há leitores.
Mas essa solução apresenta grandes problemas, se o fluxo de leitores for regular: o editor pode ter que esperar um tempo infinito.
Existe, portanto, uma segunda solução, que consiste em colocar em espera todos os leitores que enviaram seu pedido de acesso após o de um editor.
Edsger Dijkstra , que formulou esse problema, se propõe a resolvê-lo por meio de semáforos .
A solução a seguir resolve o problema dos leitores e escritores priorizando os leitores. Esta solução requer três semáforos e uma variável, a saber:
Esta solução usa os quatro métodos a seguir:
Comece a ler Commencer_Lire: P(M_Lect) SI (red) ALORS pbloque=true V(M_Lect) p(synch) FIN SI SINON lect++; V(M_Lect)Este método aumenta o número de leitores; então, se este for o primeiro leitor a tentar entrar, ele só permitirá a entrada se não houver nenhuma escrita atual. Caso contrário, o método deve esperar até que o esboço seja concluído. A utilização de dois semáforos para os editores permite induzir a prioridade aos leitores.
Terminar uma leitura Finir_Lire: P(M_Lect) lect-- SI Lect==0 ALORS V(Red) FIN SI V(M_Lect)Este método diminui o número de leitores. Então, se este for o último leitor a sair, permite que os editores entrem (se necessário).
Comece a escrever Commencer_Ecrire: P(M_Red) P(Red) SI (red or lect>0) ALORS pbloque=true V(Red) SINON red=true V(Red) V(M_Red)Este método usando o semáforo M_Red torna possível garantir que a prioridade seja dada aos leitores no final de um gravador (na verdade, o final de um gravador libera o semáforo Vermelho - liberando assim um possível leitor - antes de liberar o semáforo M_Red).
Terminar uma escrita Finir_Ecrire: V(Red) V(M_Red)Este método permite garantir que a prioridade seja dada aos leitores (de fato, liberar o semáforo vermelho libera um possível leitor antes de liberar um possível editor usando o semáforo M_Red).
Suponha que o objetivo dos leitores seja ler dados de forma assíncrona. Todos os leitores têm as informações no momento em que sua solicitação (possivelmente de uma máquina remota) foi feita.
Ou um ponteiro DATA para uma estrutura de dados contendo todas as informações disponíveis. Os editores enviarão solicitações que serão armazenadas em uma fila FILE .
Um mutex M1 protege a seguinte estrutura:
Liste de DATA : PRECEDENT DATA : ACTUEL DATA : PROCHAIN booléen : MISAJOURUm mutex M2 protege a seguinte estrutura:
File de mises à jour : FILE Date de dernière modification : DERNIER Código executado pelo leitor verrouille M1: si MISAJOUR est vrai: enfile ACTUEL dans PRECEDENT pour chaque élément de PRECEDENT: effacer l'élément si son compteur de références est nul (1) fin pour ACTUEL := PROCHAIN (2) PROCHAIN := copie de ACTUEL MISAJOUR := faux fin si récupérer un pointeur P sur ACTUEL et incrémenter son compteur de références déverrouille M1 lire dans P ... décrémenter le compteur de références de P Código executado pelo escritor verrouille M2: enfiler les modifications dans FILE si DERNIER est dépassé de 10 secondes: verrouiller M1: effectuer toute modification de FILE dans PROCHAIN vider FILE MISAJOUR := vrai (3) déverrouille M1 fin si déverrouille M2 ObservaçõesEste modelo é adequado quando as atualizações não requerem gerenciamento de transações, que os bancos de dados devem fornecer .