Sequenzielle Konsistenz angewandt

Inhaltsverzeichnis[Anzeigen]

In dem Artikel sequenzielle Konsistenz habe ich bereits das Defaul-Speichermodell vorgestellt. Dieses Modell, in dem die Aktionen aller Threads einer globalen Reihenfolge oder auch eines globalen Zeittaks folgen, besitzt einen großen Vorteil und einen großen Nachteil.

 

Aufwändige Synchronisation

Der große Vorteil ist es, dass sich die sequenzielle Konsistenz mit unserer Intuition des Verhaltens mehrerer Threads deckt, der große Nachteil ist, dass die Synchronisation aller Threads aufwändig vom System sicherzustellen ist.

Das kleine Programm synchronisiert seinen Producer-Thread mit seinem Consumer-Thread mit Hilfe der sequentiellen Konsistenz.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <atomic>
#include <iostream>
#include <string>
#include <thread>

std::string work;
std::atomic<bool> ready(false);

void consumer(){
  while(!ready.load()){}
  std::cout<< work << std::endl;   
}

void producer(){
  work= "done";
  ready=true; 
}

int main(){
  std::thread prod(producer);
  std::thread con(consumer);
  prod.join(); 
  con.join();
}

 

Die Ausgabe des Programms ist kurz uns prägnant, aber dennoch interessant.

producerConsumer

Dank der sequenziellen Konsistenz ist der Programmlauf vollkommen deterministisch. Das Programm gibt immer "done" aus.

Die Graphik bringt es auf den Punkt. Der Consumer-Thread wartet in der while-Schleife, bis die atomare Variable ready den Wert true besitzt. Ist dies der Fall, fährt der Consumer Thread mit seiner Arbeit fort

 SequenzielleKonsistenz

Dass das Programm immer "done" ausgibt, lässt sich einfach begründen. Ich nütze dazu die zwei Eigenschaften der sequenziellen Konsistenz aus. Zum einen werden die Anweisungen beider Threads in Sourcecodereihenfolge ausgeführt, zum andern sehen die Threads die Anweisungen des anderen Threads in der gleichen Reihenfolge. Damt folgen alle Operationen dem globalem Takt. Diesem Takt  folgt auch - mit Hilfe der while (!ready.load()){}-Schleife -  die Synchronisation des Producer-Threads mit dem Consumer-Thread .

Es geht aber auch deutlich formaler. In der Begrifflichkeit des Speichermodells lautet die Argumentationskette:

=> Steht für die Schlussfolgerung in den nächsten Zeilen.

    1. work= "done"  ist sequenced-before ready=true => work= "done" happens-before ready=true
    2. while(!ready.load()){} ist sequenced-before std::cout<< work << std::end l =>  while(!ready.load()){} happens-before std::cout<< work << std::endl
    3. ready=true  synchronizes-with while(!ready.load()){} => ready= true inter-thread happens-before while (!ready.load()){} => ready= true happens-before while (!ready.load()){}

=> Da die happens-before Relation transitiv ist, gilt: work= "done" happens-before ready= true happens-before while(!ready.load()){} happens-before std::cout<< work << std::endl

Von der Sequenzielle Konsistenz zur Acquire-Release-Semantik

Ein Thread sieht die Operationen eines anderen Threads und somit aller Threads in der gleichen Reihenfolge. Diese elemente Eigenschaft der sequenziellen Konsistenz gilt nicht mehr, wenn wir statt der sequenziellen Konsistenz die Acquire-Release Semantik für atomare Operationen auswählen. Hier geht C++ deutlich weiter als C# oder auch Java. Leider verlassen wir nun auch den Raum unserer natürlichen Intuition.

Bei der Acquire-Release Semantik findet die Synchronisation nicht zwischen Threads, sondern zwischen atomaren Variablen der Threads statt. So synchronisiert sich eine Schreib-Operation eines Threads mit einer Lese-Operation eines anderen Threads auf der gleichen atomaren Variable. Diese Synchronisationsbeziehungen auf der gleichen atomaren Variablen helfen, happens-before Relation zwischen atomaren Variablen und damit zwischen Threads zu erzeugen.

Wie geht's weiter?

Die Details zur Acquire-Release Semantik zusammen mit dem optimierten Spinlock aus dem Artikel  Das atomare Flag folgen im nächsten Artikel.

 

 

 

 

 

 

 

title page smalltitle page small Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library".   Hole dir dein E-Book. Unterstütze meinen Blog.

 

 

 

 

Kommentare   

0 #1 tabletki poronne 2016-02-25 08:31
I seriously love your blog.. Excellent colors &
theme. Did you create this site yourself? Please reply back as I'm
trying to create my very own website and would love to learn where
you got this from or what the theme is named.

Kudos!

Also visit my site; tabletki poronne: http://www.tabletkiporonne.pl/forum/viewthread.php?thread_id=41
Zitieren
0 #2 blogs 2016-05-07 10:58
I'm extremely pleased to find this great site. I want to
to thank you for your time just for this fantastic read!!
I definitely enjoyed every bit of it and i also have you book-marked
to check out new things on your website.

Here is my website: blogs: http://www.nabiakram.org.au/index.php/component/k2/itemlist/user/1474
Zitieren

Kommentar schreiben


Modernes C++

Abonniere den Newsletter

Inklusive zwei Artikel meines Buchs
Introduction und Multithreading

Beiträge-Archiv

Sourcecode

Neuste Kommentare