lock ={0};
öffentlich:
void Acquire_read () {
while (wahr) {
int current_value =lock.load ();
if (current_value <0) {// Schriftsteller wartet erneut
// Ergibt den Prozessor, damit der Schriftsteller eine Chance hat.
// Eine ausgefeiltere Implementierung kann eine Zustandsvariable verwenden.
weitermachen;
} else if (compare_and_swap (&lock, current_value, current_value + 1)) {
brechen; // erfolgreich erworbene Lese -Lock
}
}
}
void Release_read () {
sperren--; // Leser -Zählung Dekrement. Die Atomdekrementierung ist entscheidend.
}
void Accire_write () {
while (wahr) {
if (compare_and_swap (&lock, 0, -1)) {// Erwerben Sie Schloss, wenn keine Leser oder Schriftsteller
brechen; // erfolgreich erworbene Schreibschloss
} anders {
// Versuchen Sie es weiter, bis er erfolgreich ist, oder signalisieren Sie den Wartenstatus
weitermachen; // Spin-Wait, nicht ideal für hohe Streitigkeiten
// Eine ausgefeiltere Version kann eine Zustandsvariable verwenden, um zu verhindern, dass das Warten beschäftigt ist.
}
}
}
void Release_write () {
lock =0; // Lock -Lock
}
// Helferfunktion (Ersetzen Sie durch den Vergleich und der Tausch Ihrer Sprache)
bool compare_and_swap (std ::atomic * Ziel, int erwartet, int gewünscht) {
return target-> compare_exchange_weak (erwartet, gewünscht);
}
};
int main () {
Multipl!
// Beispielnutzung
m.acquire_read ();
std ::cout <<"Reader 1 erworbenes Lock \ n";
m.release_read ();
std ::cout <<"Reader 1 veröffentlichte Lock \ n";
m.acquire_write ();
std ::cout <<"Schriftsteller erworben Lock \ n";
M.Release_Write ();
std ::cout <<"Autor veröffentlichte Lock \ n";
m.acquire_read ();
m.acquire_read ();
std ::cout <<"Leser 2 und 3 erworbenes Lock \ n";
m.release_read ();
m.release_read ();
std ::cout <<"Leser 2 und 3 veröffentlichte Lock \ n";
Rückkehr 0;
}
`` `
Wichtige Überlegungen:
* Spinlocks: Die Methoden "Acquire_Write" und "Accire_read" verwenden geschäftige Waiting (Spinlocks). Dies ist unter hohem Streit ineffizient. Ersetzen Sie dies für den Produktionscode durch Bedingungsvariablen oder andere Synchronisationsprimitive, um die Verschwendung von CPU -Zyklen zu vermeiden.
* Hunger: Während Autoren priorisiert werden, können die Leser möglicherweise noch Hunger erleben, wenn es einen kontinuierlichen Strom von Schriftstellern gibt. Ein ausgefeilteres Warteschlangensystem könnte die Fairness verbessern.
* Atomoperationen: Die Richtigkeit dieses Schlosses hängt stark von der Atomizität des `compare_and_swap` und den Inkrement-/Dekrement -Operationen ab. Stellen Sie sicher, dass Ihre ausgewählten atomaren Operationen die erforderlichen Garantien bieten.
* Fehlerbehandlung: Eine robuste Implementierung würde die Fehlerbehandlung umfassen (z. B. Überprüfung der Rückgabewerte aus Atomoperationen).
* Skalierbarkeit: Berücksichtigen Sie für Szenarien mit hoher Konsequenz fortgeschrittenere Verriegelungsmechanismen, die für eine bessere Skalierbarkeit ausgelegt sind.
Dieses verbesserte Beispiel bietet eine robustere, wenn auch immer noch vereinfachte Implementierung. Erwägen Sie für Produktionssysteme die Verwendung etablierter Bibliotheken oder Frameworks, die gut getestete und hoch optimierte Synchronisationsprimitive bieten. Denken Sie daran, dass die Synchronisation komplex ist und potenzielle Rassenbedingungen und Leistungs Engpässe sorgfältig berücksichtigt.