• Nenhum resultado encontrado

Os métodos chamados por cada leitor e escritor são definidos na classe Database na Figura 7.21 A variá vel readerCount controla o número de leitores O semáforo mutex é usado para garantir a exclusão mútua

No documento [PT] SILBERSCHATZ - Sistemas Operacionais (páginas 158-162)

quando readerCount é atualizado. O semáforo db funciona como um semáforo de exclusão mútua para os es-

critores. Também é utilizado pelos leitores para evitar que os escritores entrem no banco de dados enquanto

este estiver sendo lido. O primeiro leitor realiza uma operação P( ) em db, evitando, assim, que algum escri-

tor entre no banco de dados. O leitor final realiza uma operação V ( ) em db. Observe que, se um escritor esti-

ver ativo no banco de dados e n leitores estiverem esperando, então um leitor será colocado na fila em db, e n

- 1 leitores serão colocados na fila em mutex. Observe também que, quando um escritor executa db.V( ), é

possível retomar a execução dos leitores em espera ou de um único escritor em espera. A selcção é feita pelo

escalonador.

138 • Sistemas Operacionais

public class Writer extends Thread

1

public W r i t e r ( i n t w, Database db) { writerNum • w;

server • db;

)

public voíd run( ) { while ( t r u e ) {

System.out.println(Mwríter • + writerNum + " is s l e e p i n g . " ) ;

Database.napping( );

System.out.println("writer " + writerNum • " wants to w r i t e . ' ) ;

server.startWrite( ) ;

// você tem acesso de e s c r i t a no banco de dados System.out.println("writer " + writerNum • " is w r i t i n g . " ) ; Database.napptng( ); server.endWrite( ): SyStem.out.println{"writer * + writerNum • " is done w r i t i n g . " ) ;

í

I

p r i v a t e Database server; p r i v a t e int writerNum; ) F i g u r a 7.20 U m escritor. public class Database

1

public Databasef ) ( readerCoimt ° 0;

mutex = new Semaphore(l); db • new Semaphore(l); J

/ / o s l e i t o r e s e escritores chamam este método para " c o c h i l a r " public s t a t i c void nappingf ) {

i n t sleepTime » (int){NAP TIME " Hath.random( ) ) ; try { Thread.sleep(sleepTime*1000); } catch(InterruptedException e) { ) ) public i n t startRead( ) { / / F i g u r a 7.22 ) public i n t endRead( ) ( / / F i g u r a 7.22 ) public void s t a r t W r i t e í ) { / / F i g u r a 7.23 J F i g u r a 7.21 O h a n c o de d a d o s para o p r o b l e m a d o s leitores-cscritores.

Sincronização de Processos • 139

public void endWrite( ) ( / / F i g u r a 7.23

p r i v a t e s t a t i c f i n a l i n t NUM_OF_READERS - 3; p r i v a t e s t a t i c f i n a l i n t NUM~OF_WRITERS = 2; private s t a t i c f i n a l i n t NAP TIME - 15;

í

p r i v a t e i n t readerCount; p r i v a t e Semaphore mutex; p r i v a t e Semaphore db; Figura 7.21 Continuação public i n t startReadí ) { mutex.P( ); ••readerCount;

/ / s ç sou o primeiro l e i t o r , informe todos / / o s outros que o banco de dados está sendo l i d o if (readerCount •• 1) db.P( ) ; mutex.V( ); return readerCount;

J

public i n t endRead( ) { mutex.P( ): —readerCount;

/ / $ e sou o último l e i t o r , informe todos

/ / o s outros que o banco de dados não está mais sendo l i d o if (readerCount -= 0)

db.V( ) ;

mutex.V( );

return readerCount; I

Figura 7.22 Métodos chamados pelos leitores.

7.6.3 O problema do jantar dos filósofos

Considere cinco filósofos que passam suas vidas meditando e comendo. Os filósofos compartilham uma mesa redonda comum cercada por cinco cadeiras, cada qual pertencente a um filósofo. No centro da mesa está uma tigela de arroz, e a mesa está posta com cinco pauzinhos (hashi) (Figura 7.24). Quando um filósofo medita, não interage com seus colegas. De vez em quando, um dos filósofos fica com fome c tenta pegar os dois pauzinhos mais próximos de si (os pauzinhos q u e estão entre ele e seus colegas da esquerda e direita). Um filósofo só pode pegar um pauzinho de cada vez. Obviamente, n i o poderá pegar um que já esteja na mão de um colega. Quando o filósofo com fome está de posse dos dois pauzinhos ao mesmo tempo, ele poderá co-

mer sem soltá-los. Quando termina de comer, o filósofo solta os pauzinhos e volta a meditar.

O problema do jantar dos filósofos é considerado um problema clássico de sincronização, não por causa de sua importância prática, nem porque os cientistas da computação não gostam de filósofos, mas porque ele

é um exemplo de uma vasta classe de problemas de controle de concorrência. E uma representação simples

140 • Sistemas Operacionais

publíc void startWrtteí ) { db.P( );

I

public void endWrite( ) ( db.V( ) ;

)

Figura 7.23 Métodos chamados pelos escritores.

Figura 7.24 O jantar dos filósofos.

Uma solução simples consiste em representar cada pauzinho por um semáforo. Um filósofo tenta agarrar o pauzinho executando uma operação P naquele semáforo; o filósofo solta o pauzinho executando a opera- ção V nos semáforos apropriados. Assim, os dados compartilhados são:

Semaphore chopStick[ ] • new Semaphore[5];

em que todos os elementos de chopStick são inicializadoscomo 1. A estrutura do f i l ó s o f o / é apresentada na Figura 7.25.

whtle(tnie) (

//pega o pauzinho da esquerda chop$tick[i).P( );

//pega o pauzinho da direita chopStick[(i + 1) % 5].P( ); eating( );

//devolve o pauzinho da esquerda chopStick[i].V( );

//devolve o pauzinho da direita chopStick[(i • 1) H 5].V( ); thinkingí );

I

Figura 7.25 A estrutura do filósofo /'.

Embora essa solução garanta que dois filósofos vizinhos não estarão comendo simultaneamente, ela deve ser rejeitada porque tem a possibilidade de criar um deadlock. Vamos supor que todos os cinco filósofos f i - quem com fome ao mesmo tempo, e cada um pegue o pauzinho à sua esquerda. Todos os elementos de chopS- t l c k agora serão iguais a 0. Quando cada filósofo tentar pegar o pauzinho à sua direita, ficará esperando para sempre.

Várias soluções possíveis para o impasse são listadas a seguir. Essas soluções evitam o deadlock, impondo restrições aos filósofos:

Sincronização de Processos » 141

• Permitir a presença de no máximo quatro filósofos ao mesmo tempo à mesa.

• Permitir que um filósofo pegue o seu pauzinho apenas se os dois pauzinhos estiverem disponíveis (ob-

serve que o filósofo deverá pegá-los em uma seção crítica).

• Usar uma solução assimétrica; por exemplo, um filósofo ímpar pega primeiro o pauzinho à sua es-

querda e depois o da sua direita, enquanto um filósofo par pega o da direita e depois o da esquerda.

Na SeçãO 7.7, apresentamos uma solução ao problema do jantar dos filósofos que não incorre em dead-

locks. Qualquer solução satisfatória ao problema do jantar dos filósofos deverá evitar a possibilidade de um

dos filósofos morrer de fome. Uma solução livre de impasse, ou de deadlock, não elimina necessariamente a

possibilidade de paralisação.

7.7 • Monitores

Embora os semáforos forneçam um mecanismo conveniente e eficaz para a sincronização de processos, seu

No documento [PT] SILBERSCHATZ - Sistemas Operacionais (páginas 158-162)

Outline

Documentos relacionados