Home Hardware Networking Programmazione Software Domanda Sistemi
Conoscenza del computer >> hardware >> Electronic Book Readers >> .

Implementare un blocco per scrittori-single-single-scrittrice in base alle istruzioni di confronto e swap che i lettori non possono superare gli scrittori in attesa?

Questa implementazione utilizza un'istruzione COMPAT-and-SWAP (CAS) per gestire un blocco per il canale-single-single-scrittore. Dai la priorità agli scrittori, garantendo che i lettori non possano morire di fame gli scrittori. Tuttavia, non utilizza sofisticati meccanismi di accodamento per l'equità tra i lettori, quindi alcuni lettori potrebbero sperimentare attese più lunghe di altri.

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 blocco ={0};

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 * target, int previsto, int desiderato) {

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.

 

hardware © www.354353.com