`` `Python
importar rosqueamento
tempo de importação
Classe ReaderWriterLock:
"" "
Uma solução de monitor para o problema dos leitores-escritores.
Atributos:
Read_Count (int):Número de leitores atualmente acessando o recurso.
write_count (int):número de escritores atualmente acessando o recurso.
Readers_waiting (Lista):Lista de leitores esperando para acessar o recurso.
Writers_waiting (Lista):Lista de escritores esperando para acessar o recurso.
Lock (Threading.lock):Um bloqueio para proteger a seção crítica.
"" "
def __init __ (self):
self.read_count =0
self.write_count =0
self.readers_waiting =[]
self.writers_waiting =[]
self.lock =Threading.lock ()
def adquire_read (self):
"" "
Adquire um bloqueio de leitura.
"" "
com self.lock:
enquanto self.write_count> 0 ou self.writers_waiting:
Self.readers_waiting.append (shinging.current_thread ())
self.lock.release ()
Threading.current_thread (). wait ()
self.lock.acquire ()
self.read_count +=1
def Release_read (self):
"" "
Libera um bloqueio de leitura.
"" "
com self.lock:
self.read_count -=1
se self.read_count ==0 e self.writers_waiting:
writer =self.writers_waiting.pop (0)
writer.Notify ()
def adquire_write (self):
"" "
Adquire um bloqueio de gravação.
"" "
com self.lock:
enquanto self.read_count> 0 ou self.write_count> 0 ou self.writers_waiting:
Self.writers_waiting.append (shinging.current_thread ())
self.lock.release ()
Threading.current_thread (). wait ()
self.lock.acquire ()
self.write_count +=1
def Release_write (self):
"" "
Libera um bloqueio de gravação.
"" "
com self.lock:
self.write_count -=1
Se self.readers_waiting:
leitor =self.readers_waiting.pop (0)
leitor.Notify ()
Classe Reader (Threading.Thread):
"" "
Um tópico do leitor.
"" "
def __init __ (self, bloqueio):
super () .__ init __ ()
self.lock =bloqueio
def run (self):
para _ no intervalo (5):
self.lock.acquire_read ()
print (f "leitor {self.name} está lendo")
time.sleep (0,5)
self.lock.release_read ()
print (f "leitor {self.name} terminado lendo")
escritor de classe (Threading.Thread):
"" "
Um tópico do escritor.
"" "
def __init __ (self, bloqueio):
super () .__ init __ ()
self.lock =bloqueio
def run (self):
para _ no intervalo (5):
self.lock.acquire_write ()
print (f "writer {self.name} está escrevendo")
time.sleep (1)
self.lock.release_write ()
print (f "Writer {self.name} terminado escrita")
Se __name__ =="__main__":
Lock =ReaderWriterLock ()
Readers =[Leitor (Lock) para _ no intervalo (3)]
Escritores =[Writer (Lock) para _ no intervalo (2)]
Para o leitor nos leitores:
leitor.start ()
Para escritores em escritores:
writer.start ()
Para o leitor nos leitores:
leitor.join ()
Para escritores em escritores:
writer.join ()
`` `
Explicação: 1.
`leitorwriterlock` classe: - `read_count`,` write_count`:rastreia o número de leitores e escritores ativos.
- `Readers_waiting`,` Writers_waiting`:listas para manter threads aguardando acesso.
- `Lock`:um mutex para proteger a seção crítica em que contadores e listas são modificados.
2.
`adquirir_read`: - adquire um bloqueio de leitura:
- Primeiro verifica se algum escritor está acessando ou esperando. Nesse caso, o leitor é adicionado à lista `Readers_waiting` e espera.
- Depois que a condição é atendida, o `read_count 'do leitor é incrementado, significando sua entrada.
3.
`release_read`: - libera um bloqueio de leitura:
- diminui o `read_count`.
- Se nenhum mais leitores estiver ativo e os escritores estão esperando, o primeiro escritor em `writers_waiting` será notificado.
4.
`adquirir_write`: - Adquire um bloqueio de gravação:
- Primeiro, ele verifica se algum leitor ou escritor está acessando ou esperando atualmente. Nesse caso, o escritor é adicionado a `writers_waiting` e espera.
- Depois que a condição é atendida, o `write_count 'do escritor é incrementado, significando sua entrada.
5.
`release_write`: - libera um bloqueio de gravação:
- diminui o `write_count`.
- Se os leitores estão esperando, o primeiro leitor em `Readers_waiting` será notificado.
6.
`leitor` e` writer` classes: - Essas classes representam tópicos de leitor e escritor.
- Eles usam os métodos `adquire_read/adquire_write` e` release_reead/release_write` para acessar o recurso compartilhado.
como funciona: - O monitor garante acesso exclusivo ao recurso para escritores.
- Os leitores podem ler simultaneamente, mas nenhum leitor pode ler enquanto um escritor está escrevendo.
- Os threads de espera são gerenciados em filas e notificados quando o recurso estiver disponível.
Nota: - O método `notify ()` de um thread é usado para acordar um thread em espera.
- Este código utiliza o conceito de uma variável de condição (implícita por `wait ()` e `notify ()` neste exemplo) para lidar com a espera e a notificação do thread.