Sistemas Operacionais Sincronização: Semáforos Problema dos Leitores/Escritores
Autoria Autores Eduardo André Mallmann 0905/96-9 João Paulo Reginatto 1530/96-0 Local Instituto de Informática UFRGS disciplina: Sistemas Operacionais II Versão: V13-1, ago 2012-2 C. Geyer
Baseado em que?? Essas transparências são baseadas na apostila do Prof. Simão Sirineo Toscani - Introdução aos Sistemas Operacionais - 1996
Especificação do Problema O problema de sincronização do tipo leitores/escritores surge quando vários processos acessam para: leitura ou (modo exclusivo) escrita uma mesma estrutura de dados.
Características do Problema Problema básico de exclusão mútua Acesso concorrente a um recurso como um arquivo Não possui os casos de sinalização do problema do produtor/consumidor Buffer cheio Buffer vazio Mas o problema de excluão mútua é mais complexo que no produtor/cosumidor
Processo Leitor Leitor é aquele processo que acessa mas não altera a informação. Dessa forma notamos que, podemos ter vários processos leitores utilizando ao mesmo tempo a informação compartilhada uma vez que nenhum desses processos realizará alterações na mesma.
Processo Escritor Por sua vez o processo escritor é aquele que acessa a informação e faz alterações na mesma. Este acesso deverá ser exclusivo a este processo já que o dado será alterado. Usualmente um leitor não poderá ler durante a escrita
Ausência de sinalização Leitores Se considera que sempre há algo a ler Se a leitura for sequencial, o final de arquivo é um caso normal O leitor recebe um aviso de final de arquivo Não fica bloqueado
Ausência de sinalização Escritores Se considera que sempre há espaço (disco,...) para acréscimo de dados Em caso mais realista O escritor recebe um aviso de overflow E não fica bloqueado
O exemplo No exemplo que será mostrado a seguir usaremos como informação a ser compartilhada um arquivo global, acessado por vários processos.
Sincronização Então a sincronização a ser implementada no acesso ao arquivo global deverá permitir que qualquer número de leitores tenha acesso a ele simultaneamente. Entretanto, qualquer processo escritor alterando o arquivo deverá ter acesso exclusivo ao mesmo.
Soluções Serão mostradas duas soluções para o problema A diferença entre elas é que a primeira dá prioridade aos leitores enquanto a segunda dá prioridade de acesso ao arquivo para os escritores.
Soluções Serão mostradas duas soluções para o problema dar prioridade significa que em certas situações especiais de concorrência, somente os processos com prioridade (grupo de) conseguirão acessar o arquivo até todo o grupo acessar o arquivo (grupo de) processos sem prioridade Esperam pelo final do 1º grupo
Prioridade aos leitores A primeira solução garante a prioridade de acesso aos leitores. Escritores esperam pelo final de grupo parcial de leitores Espera poderia ser infinita
Prioridade aos leitores Primeiro subproblema: como manter acesso exclusivo ao arquivo entre os leitores e qualquer escritor? entre os escritores?
Prioridade aos leitores Primeiro subproblema: como manter acesso exclusivo ao arquivo entre Solução: os leitores e qualquer escritor? entre os escritores? Um semáforo do tipo mutex
Prioridade aos leitores Segundo subproblema: Como, tendo um mutex entre leitores e escritores, garantir que vários leitores possam acessar o arquivo concorrente? Ao menos nas situações usuais
Prioridade aos leitores Segundo subproblema: Como, tendo um mutex entre leitores e escritores, garantir que vários leitores possam acessar o arquivo concorrente? Solução (idéia): Somente um leitor bloqueia os escritores (e eventualmente bloqueia os outros leitores) Novo subproblema Qual leitor?
Prioridade aos leitores Novo subproblema Qual leitor? Solução O primeiro Como implementar o controle do primeiro leitor?
Prioridade aos leitores Como implementar o controle do primeiro leitor? Solução: Através de um contador de leitores O primeiro leitor executa a primitiva P(mutex) Concorre com os escritores Os outros não executam P(mutex) Não concorrem com os escritores se o 1º ganhou Como e quando liberar o acesso aos escritores?
Prioridade aos leitores Como e quando liberar o acesso aos escritores? Solução: O último leitor libera o acesso aos escritores Executando a primitiva V(mutex) Se não houver último leitor (sempre há um novo leitor concorrente)?
Prioridade aos leitores Se não houver último leitor (sempre há um novo leitor concorrente)? Ou os grupos de leitores não são intercalados por períodos sem leitor Solução Os escritores podem morrer de fome As operações sobre o contador de leitores necessitam de sincronização?
Prioridade aos leitores As operações sobre o contador de leitores necessitam de sincronização? Resposta: sim; mais um semáforo do tipo mutex seção crítica somente entre leitores Quando um escritor estiver escrevendo, o que deve ocorrer com novos leitores que pedem leitura?
Prioridade aos leitores Quando um escritor estiver escrevendo, o que deve ocorrer com novos leitores que pedem leitura? Resposta: devem ficar bloqueados Onde? Mutex entre leitores e escritores? Ou mutex do contador de leitores? Ou um novo mutex?
Prioridade aos leitores Onde? Mutex entre leitores e escritores? Ou mutex do contador de leitores? Ou um novo mutex? Resposta: mutex do contador de leitores Observação: O primeiro leitor está em...?
Prioridade aos leitores Implementação Serão utilizadas as seguintes variáveis: duas variáveis semáforas: mutex e ambas inicializadas em 1. exclusão mútua uma variável inteira nl inicializada em 0 que contará o número de processos leitores acessando o arquivo.
Implementação Abaixo mostramos o (pseudo) código que cada processo (leitor ou escritor) deve executar. Semáforo mutex, e initial (1, 1) Integer nl initial 0 P(mutex) nl:= nl+1 if nl = 1 then P(e) V(mutex) Lê P(mutex) nl := nl-1 if nl = 0 then V(e) V(mutex) Leitor P(e) Escreve V(e) Escritor
Comentários sobre o código Agora o código apresentado será comentado: Procedimento do Leitor: P(mutex) variável nl esta chamada faz com que apenas um leitor altere a nl := nl+1 incrementa nl, número de leitores ativos if nl = 1 then P(e) se for o primeiro leitor a ter acesso, bloqueia o acesso por escritores V(mutex) libera o acesso de leitores à variável nl Depois de executar estas instruções o leitor tem acesso ao arquivo global. Observação: P(mutex) bloqueia novos leitores quando...
Comentários sobre o código Após ler o arquivo o leitor executa estas instruções: P(mutex) variável nl novamente faz com que apenas um leitor altere a nl := nl-1 decrementa nl, número de leitores ativos if nl = 0 then V(e) se for o último leitor a deixaro o arquivo, libera o acesso por escritores V(mutex) libera o acesso de leitores à variável nl
Comentários sobre o código No processo escritor são executadas as seguintes instruções P(e) faz com que o escritor tenha acesso exclusivo ao arquivo Escreve no arquivo V(e) libera o acesso ao arquivo
Resumo da solução Prioridade aos leitores Escritores podem morrer de fome Quando há sempre ao menos 1 leitor lendo Grupo infinito 1 semáforo tipo lock entre escritores Também bloqueia 1º leitor 1 contador de leitores -> 1º leitor 1 semáforo tipo lock entre leitores Acesso ao contador
Exercícios Questão A) na situação de 1 ou mais leitores lendo, onde escritores ficam bloqueados? Questão B) na situação de 1 escritor escrevendo, onde os leitores ficam bloqueados (considere 2 ou mais leitores)? Questão C) quando 1 escritor termina sua escrita e leitores e escritores estão esperando, quem prossegue?
Solução 2: prioridade aos escs. Essa segunda solução garante a prioridade de acesso aos escritores. Requisitos Anteriores Múltiplos leitores concorrentes 1 único escritor escrevendo Novo Enquanto houver escritores em um lote de escritores concorrentes : leitores ficam bloqueados
Solução 2: prioridade aos escs. Serão utilizadas as seguintes variáveis: uma variável inteira ne, inicializada em zero, para contar o número de processos que esperam para escrever no arquivo ne = 1 um está escrevendo e nenhum está esperando ne = 2: um escrevendo e um esperando duas variáveis semáforas mx e l, inicializadas em 1 mx: acesso exclusivo a ne l: fila de leitores caso haja escritores escrevendo Similar ao controle de 1º leitor, agora para 1º escritor
Solução 2: prioridade aos escs. Serão utilizadas as seguintes variáveis: Além das varíaveis da solução anterior mutex e nl para controle da quantidade de leitores e para exclusão mútua na escrita
Implementação da sol. 2 P(l) P(mutex) nl := nl+1 if nl = 1 then P(e) V(mutex) V(l) Lê P(mutex) nl := nl-1 if nl = 0 then V(e) V(mutex) Semáforo mutex, e initial (1, 1) Integer nl initial 0 Integer ne initial 0 Semáforo mx, l initial (1,1) Escritor Leitor P(mx) ne := ne+1 if ne = 1 then P(l) V(mx) P(e) Escreve V(e) P(mx) ne := ne-1 if ne = 0 then V(l) V(mx)
Comentários sobre o código Leitor (1): P(l) tenta obter permissão de leitor (sobre escritores) P(mutex) restringe acesso à variável nl nl := nl+1 incrementa número de leitores ativos if nl = 1 then P(e) se for primeiro leitor ativo bloqueia escritores V(mutex) libera acesso a nl V(l) libera semáforo leitor; notar que escritores bloqueados Depois de executar estas instruções o processo lê o arquivo A parte interna ao mutex é idêntica à da solução anterior
Comentários sobre o código Leitor (2): Depois da leitura do arquivo são estas instruções que o processo executa: P(mutex) faz com que apenas um leitor altere a variável nl nl := nl-1 decrementa nl, número de leitores ativos if nl = 0 then V(e) se for o último leitor a terminar a leitura, libera o acesso por escritores V(mutex) libera o acesso de leitores a variável nl Como vemos esta parte do código é idêntica ao outro algoritmo.
Comentários sobre o código Escritor : P(mx) V(mx) P(e) faz com que apenas um escritor altere a variável ne ne := ne+1incrementa número de escritores na fila de espera if ne = 1 then P(l) se for o primeiro escritor, fecha semáforo de leitores Altera arquivo V(e) P(mx) V(mx) libera semáforo da variável ne fecha semáforo de escritor abre semáforo de escrita fecha semáforo para alteração de ne ne := ne-1 decrementa número de escritores na fila if ne = 0 then V(l) se processo estava escrevendo, libera leitura libera acesso a ne
Comentários Como podemos ver o raciocínio utilizado nesta solução é similar ao usado na solução anterior para leitores, agora tratando de bloquear os processos leitores no 1º escritor
Comentários Como evitar que leitores continuamente concorrentes bloqueiem todos os escritores? Solução: Um novo semáforo l, inicializado em 1 (aberto) Fechado (P(l)) pelo primeiro escritor de um lote de escritores concorrentes Aberto (V(l)) pelo último escritor do lote Esse semáforo, quando fechado, bloqueia todos os leitores
Comentários Observação uso semáforos de bloqueio Semáforo e (escritores) em escritores Tipo seção crítica na escrita Semáforo l em leitores Somente controle de blocos de leitores separados pelo 1º escritor de bloco de escritores Se não há escritores, cada leitor abre e fecha Sem efeito
Comentários Note ainda que esta solução não garante prioridade absoluta para os escritores. Consideremos a situação de ne =1: lote de um (1) único escritor com 5 leitores na fila do semáforo l. Após a escrita o último escritor do lote muda ne para 0 e libera o 1º leitor em l e mais tarde surge um novo escritor (novo lote)
Comentários Neste caso, o novo escritor deverá esperar os leitores acabarem a leitura para poder acessar o arquivo. Importante: somente os leitores que já estavam em espera em l antes da chegada do novo escritor No nosso exemplo, 5 leitores Somente se semáforo com fila FIFO
Exercício Exercício A: No caso do exemplo com 5 leitores obtendo o direito de leitura após o fim do lote atual (finito) de escritores e considerando que durante a leitura, surja um novo escritor Explique como fica a fila (prioridade) entre (mais) leitores e escritores? Obs: considere semáforos com fila FIFO
Prioridade total aos escritores? Então, para os escritores obterem prioridade total para os escritores poderíamos criar um semáforo mz inicializado em 1 e colocar operações P(mz) e V(mz), respectivamente antes de P(r) e depois de V(r), no código dos leitores. Desta maneira a fila do semáforo r passará a ter no máximo um processo leitor.
Conclusão Aqui acaba este mini-curso. Nele foi apresentado o problema dos leitores/escritores assim como duas soluções para este problema utilizando o conceito de semáforos. Esperamos que esses conceitos lhe tenham sido úteis.
Exercícios Exercício A) Escreva o código da 3a solução sugerida nos últimos slides (mais o semáforo mz) Analise seu comportamento; por exemplo, é possível haver vários leitores concorrentes? Justifique. Exercício B) Porque é necessário manter o semáforo e sobre os escritores com contador associado (nl) na solução prioridade aos escritores?
Revisão Problema dos leitores/escritores Caracterize os leitores Caracterize os escritores Qual a diferença na questão de acesso a recurso comum com relação ao problema dos produtores/consumidores? Quais as diferenças nas questões de exceção com relação ao problema dos produtores/consumidores?
Revisão Como resolver o problema de acesso concorrente entre escritores? Como garantir acesso concorrente entre leitores mas evitar entre os leitores e os escritores? Algum outro semáforo é necessário? Tipo? Motivo? Explique a prioridade aos leitores