I umgesetzt einen Spin-Lock mit C++ 11 Atom-Bibliothek:Warum funktioniert Spinlock mit std :: memory_order_relaxed korrekt?
class SpinLock {
atomic_bool latch_;
public:
SpinLock() :latch_(false){
}
void lock() {
while(tryLock() == false);
}
bool tryLock() {
bool b = false;
return latch_.compare_exchange_weak(b,true,std::memory_order_relaxed);
}
void unlock() {
latch_.store(false,std::memory_order_relaxed);
}
};
I durch Laichen mehr Threads, die Richtigkeit wie folgt getestet:
static int z = 0;
static SpinLock spinLock;
static void safeIncrement(int run) {
while(--run >= 0) {
std::lock_guard<SpinLock> guard(spinLock);
++z;
}
}
static void test(int nThreads =2) {
std::vector<std::thread*> workers(nThreads);
z = 0;
for(auto& ptr : workers) ptr = new std::thread(safeIncrement,1<<20);
for(auto ptr : workers) ptr->join();
cout<<"after increment: " <<z << " out of " << (1<<20) * nThreads<<endl;
for(auto ptr : workers) delete ptr;
}
int main() {
test(4);
return 0;
}
Ich bin die insgesamt am Ende überrascht fügt als richtiger Wert mit entspannter Reihenfolge. Durch diesen Artikel: http://en.cppreference.com/w/cpp/atomic/memory_order bedeutet lockere Reihenfolge "es gibt keine Synchronisation oder Reihenfolge Einschränkungen", so dass die Änderung von einem Thread nicht von anderen sichtbar sein soll, oder? Warum ist es immer noch richtig?
(Der Test läuft auf Intel (R) Core (TM) i5-3337U CPU @ 1.80GHz)
EDIT: (dank Maxim Kommentar) Aktualisiert das Code: Initialisierung Datenelement in dem SpinLock, und Aktualisieren des Testcodes.
Stellen Sie den vollständigen Testquellcode bereit. –
Es gibt keine Initialisierung von 'SpinLock :: latch_', der Anfangswert ist unbestimmt. –