Esta implementação usa uma instrução de comparação e troca (CAS) para gerenciar um bloqueio de múltiplos leitores-single-writer. Ele prioriza os escritores, garantindo que os leitores não possam morrer de fome. No entanto, ele não usa mecanismos sofisticados de filas para justiça entre os leitores, para que alguns leitores possam experimentar esperas mais longas que outras.
Esse código é conceitual e precisa ser adaptado a uma linguagem de programação específica e suas operações atômicas. A função `compare_and_swap` é um espaço reservado; Você precisará substituí -lo pelo equivalente do seu idioma (por exemplo, `std ::atomic_compare_exchange_weak` em c ++).
`` `c ++
#include
// Supondo que números inteiros atômicos estejam disponíveis. Substitua pelo equivalente do seu idioma.
// Observe que o uso de um único número inteiro atômico pode ter implicações de desempenho
// para um sistema de alta concorrência. Para o código no nível da produção, considere outro
// Estruturas de dados para melhor escala (por exemplo, filas atômicas).
#include
Classe MultiLeadersinglewriterlock {
privado:
// 0:desbloqueado,> 0:Número de leitores, -1:Writer Waiting
std ::atomic Lock ={0};
público:
void adquirir_read () {
while (true) {
int current_value =Lock.load ();
if (current_value <0) {// Writer Waiting, tente novamente
// produz o processador para que o escritor tenha uma chance.
// Uma implementação mais sofisticada pode usar uma variável de condição.
continuar;
} else if (compare_and_swap (&bloqueio, current_value, current_value + 1)) {
quebrar; // Adquirido com sucesso LEAD LOCK
}
}
}
void release_read () {
trancar--; // Diminua a contagem de leitores. O decréscimo atômico é crucial.
}
void adquirir_write () {
while (true) {
if (compare_and_swap (&bloqueio, 0, -1)) {// adquira bloqueio se não houver leitores ou escritores
quebrar; // Adquirido com êxito Lock Write
} outro {
// continua tentando até bem -estar ou sinalizar o status de espera
continuar; // spin-wait, não é ideal para alta contenção
// Uma versão mais sofisticada pode usar uma variável de condição para evitar a espera ocupada.
}
}
}
void release_write () {
bloqueio =0; // Libere o bloqueio
}
// função auxiliar (substitua pela comparação e troca do seu idioma)
bool compare_and_swap (std ::atomic * alvo, int esperado, int desejado) {
return Target-> compare_exchange_weak (esperado, desejado);
}
};
int main () {
MultiPlereaderSlertingWriterlock m;
// Exemplo de uso
m.acquire_read ();
std ::cout <<"leitor 1 adquirido bloqueio \ n";
M.Release_Read ();
std ::cout <<"Leitor 1 Lank Lank \ n";
m.acquire_write ();
std ::cout <<"Writer adquiriu Lock \ n";
M.Release_write ();
std ::cout <<"Writer lançado Lock \ n";
m.acquire_read ();
m.acquire_read ();
std ::cout <<"O leitor 2 e 3 adquirido bloqueio \ n";
M.Release_Read ();
M.Release_Read ();
std ::cout <<"Leitor 2 e 3 Lank Lock \ n";
retornar 0;
}
`` `
Considerações importantes:
* spinlocks: Os métodos `adquirir_write` e` adquirir_read` usam pedidos de espera (spinlocks). Isso é ineficiente sob alta disputa. Para o código de produção, substitua -o por variáveis de condição ou outras primitivas de sincronização para evitar desperdiçar ciclos de CPU.
* fome: Embora os escritores sejam priorizados, os leitores ainda podem experimentar a fome se houver um fluxo contínuo de escritores. Um sistema de filas mais sofisticado poderia melhorar a justiça.
* operações atômicas: A correção desse bloqueio depende muito da atomicidade das operações `compare_and_swap` e incremento/decremento. Verifique se as operações atômicas escolhidas fornecem as garantias necessárias.
* Manuseio de erro: Uma implementação robusta incluiria o tratamento de erros (por exemplo, verificação de valores de retorno das operações atômicas).
* escalabilidade: Para cenários de alta concorrência, considere mecanismos de travamento mais avançados projetados para melhor escalabilidade.
Este exemplo aprimorado fornece uma implementação mais robusta, embora ainda simplificada. Para sistemas de produção, considere o uso de bibliotecas ou estruturas estabelecidas que fornecem primitivas de sincronização bem testadas e altamente otimizadas. Lembre -se de que a sincronização é complexa e requer uma consideração cuidadosa de possíveis condições de corrida e gargalos de desempenho.