lock ={0};
offentlig:
void Acquire_read () {
medan (sant) {
int current_value =lock.load ();
if (current_value <0) {// författare väntar, försök igen
// Ge processorn så att författaren har en chans.
// En mer sofistikerad implementering kan använda en tillståndsvariabel.
fortsätta;
} annars om (jämföra_and_swap (&lås, current_value, current_value + 1)) {
bryta; // Förvärvat läslås framgångsrikt
}
}
}
void release_read () {
låsa--; // MECLESS LÄSARE COUNT. Atomisk minskning är avgörande.
}
void Acquire_write () {
medan (sant) {
if (jämför_and_swap (&lås, 0, -1)) {// förvärva lås om inga läsare eller författare
bryta; // Förvärvade framgångsrikt skrivlås
} annat {
// Fortsätt försöka tills de är framgångsrika eller signalera väntestatusen
fortsätta; // spin-wait, inte idealisk för hög stridighet
// En mer sofistikerad version kan använda en tillståndsvariabel för att förhindra upptagen väntan.
}
}
}
void release_write () {
lås =0; // Release Lock
}
// Helper Function (Ersätt med ditt språks jämförelse och byte)
BOOL COMPARE_AND_SWAP (std ::atomic * mål, int förväntat, int önskvärt) {
returnera mål-> jämför_exchange_weak (förväntat, önskat);
}
};
int main () {
MultipleadersingleWriterLock M;
// Exempelanvändning
m.acquire_read ();
std ::cout <<"Reader 1 förvärvade lås \ n";
m.release_read ();
std ::cout <<"Reader 1 släppt lås \ n";
m.acquire_write ();
std ::cout <<"författare förvärvade lås \ n";
m.release_write ();
std ::cout <<"författare släppte lås \ n";
m.acquire_read ();
m.acquire_read ();
std ::cout <<"Reader 2 och 3 förvärvade lås \ n";
m.release_read ();
m.release_read ();
std ::cout <<"Reader 2 och 3 släppt lås \ n";
return 0;
}
`` `
Viktiga överväganden:
* spinlocks: Metoderna `Acquire_write` och` Acquire_Read 'använder upptagna väntande (spinlocks). Detta är ineffektivt under hög stridighet. För produktionskod, byt ut detta med tillståndsvariabler eller andra synkroniseringsprimitiva för att undvika att slösa CPU -cykler.
* svält: Medan författare prioriteras, kan läsarna fortfarande uppleva svält om det finns en kontinuerlig ström av författare. Ett mer sofistikerat kösystem kan förbättra rättvisan.
* atomiska operationer: Låsets korrekthet förlitar sig starkt på atomiciteten i "Comfare_and_Swap" och inkrement/minskningsoperationer. Se till att din valda atomoperation ger nödvändiga garantier.
* Felhantering: En robust implementering skulle inkludera felhantering (t.ex. kontrollera för returvärden från atomoperationer).
* skalbarhet: För scenarier med hög sammanfattning, överväga mer avancerade låsmekanismer utformade för bättre skalbarhet.
Detta förbättrade exempel ger en mer robust, men fortfarande förenklad implementering. För produktionssystem kan du överväga att använda etablerade bibliotek eller ramar som ger väl testade och högt optimerade synkroniseringsprimitiva. Kom ihåg att synkronisering är komplex och kräver noggrant övervägande av potentiella rasförhållanden och prestanda flaskhalsar.