Questo codice è concettuale e deve essere adattato a un linguaggio di programmazione specifico e alle sue operazioni atomiche. La funzione `confront_and_swap` è un segnaposto; Dovrai sostituirlo con l'equivalente della tua lingua (ad esempio, `std ::atomic_compare_exchange_weak` in c ++).
`` `C ++
#include
// Supponendo che siano disponibili numeri interi atomici. Sostituisci con l'equivalente della tua lingua.
// Si noti che l'uso di un singolo intero atomico potrebbe avere implicazioni per le prestazioni
// per un sistema ad alta concorrenza. Per il codice a livello di produzione, considera gli altri
// Strutture di dati per un migliore ridimensionamento (ad es. Code atomiche).
#include
classe multiplereadersinglewriterlock {
privato:
// 0:sbloccato,> 0:numero di lettori, -1:Writer Waiting
std ::atomic
pubblico:
void acquisire_read () {
while (vero) {
int current_Value =Lock.load ();
if (current_value <0) {// writer waiting, riprova
// produce il processore in modo che lo scrittore abbia una possibilità.
// Un'implementazione più sofisticata potrebbe utilizzare una variabile di condizione.
continuare;
} else if (confront_and_swap (&block, current_value, current_value + 1)) {
rottura; // blocco di lettura acquisito correttamente
}
}
}
void release_read () {
serratura--; // Decremento del conteggio dei lettori. Il decremento atomico è cruciale.
}
void acquisire_write () {
while (vero) {
if (confront_and_swap (&lock, 0, -1)) {// Acquisisci lock se nessun letto o scrittore
rottura; // blocco di scrittura acquisito correttamente
} altro {
// Continua a provare fino al successo o segnala lo stato di attesa
continuare; // Spin-Wait, non ideale per l'alta contesa
// Una versione più sofisticata potrebbe utilizzare una variabile di condizione per impedire l'attesa impegnata.
}
}
}
void release_write () {
Lock =0; // Blocco di rilascio
}
// funzione helper (sostituire con il linguaggio e lo scambio del tuo linguaggio)
bool confront_and_swap (std ::atomic
restituire target-> confront_exchange_weak (previsto, desiderato);
}
};
int main () {
Multiplereadersinglewriterlock m;
// Utilizzo di esempio
M.ACQUIRE_READ ();
std ::cout <<"Reader 1 acquisito blocco \ n";
m.release_read ();
std ::cout <<"Reader 1 ha rilasciato Lock \ n";
M.ACQUIRE_WRITE ();
std ::cout <<"writer acquisito block \ n";
M.Release_Write ();
std ::cout <<"scrittore rilasciato Lock \ n";
M.ACQUIRE_READ ();
M.ACQUIRE_READ ();
std ::cout <<"Reader 2 e 3 acquisito blocco \ n";
m.release_read ();
m.release_read ();
std ::cout <<"Reader 2 e 3 rilasciato Lock \ n";
restituzione 0;
}
`` `
Considerazioni importanti:
* Spinlocks: I metodi `acquisito_write` e` acquisito_read` usano impegnati (spinlocks). Ciò è inefficiente sotto elevata contesa. Per il codice di produzione, sostituisci questo con variabili di condizione o altre primitive di sincronizzazione per evitare di sprecare cicli della CPU.
* fame: Mentre gli scrittori hanno la priorità, i lettori potrebbero ancora sperimentare la fame se esiste un flusso continuo di scrittori. Un sistema di accodamento più sofisticato potrebbe migliorare l'equità.
* Operazioni atomiche: La correttezza di questo blocco si basa fortemente sull'atomicità delle operazioni `confront_and_swap` e incremento/decremento. Assicurati che le operazioni atomiche scelte forniscano le garanzie necessarie.
* Gestione degli errori: Un'implementazione robusta includerebbe la gestione degli errori (ad es. Verifica dei valori di ritorno dalle operazioni atomiche).
* Scalabilità: Per scenari ad alta concorrenza, considerare meccanismi di blocco più avanzati progettati per una migliore scalabilità.
Questo esempio migliorato fornisce un'implementazione più robusta, sebbene ancora semplificata. Per i sistemi di produzione, considerare l'uso di librerie o framework consolidati che forniscono primitivi di sincronizzazione ben testati e altamente ottimizzati. Ricorda che la sincronizzazione è complessa e richiede un'attenta considerazione delle potenziali condizioni di razza e dei colli di bottiglia delle prestazioni.
Informazioni correlate
hardware © www.354353.com