Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mo Jul 14, 2025 04:29

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Jan 24, 2011 21:08 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 03, 2002 22:12
Beiträge: 2105
Wohnort: Vancouver, Canada
Programmiersprache: C++, Python
Hi,

ich habe bisher bei Threads immer nur Mutex'e benutzt. Kam und komme damit wunderbar zurecht.. Allerdings gibt es ja noch diverse andere Methoden um threads zu synchronisieren etc.

Kann mir jemand erklären was die unterschiede zwischen z.B. Mutex, SpinLock und AtomicOperations sind? Hab zwar bei Wikipedia schon alles durchgelesen, werd aber nich wirklich schlau daraus..

Und wie benutzt man die verschiedenen Methoden? Geht es nur wenn das OS eine funktion dafür bietet oder sind das dinge die man selber implementieren muß?

Danke,
Aya~


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jan 25, 2011 10:41 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Geht es nur wenn das OS eine funktion dafür bietet oder sind das dinge die man selber implementieren muß?

Vom selbst implementieren würde ich abraten, das ist recht fehleranfällig. Suche dir eine Library die die entsprechenden Funktionen anbietet.

Eine AtomicOperation sorgt dafür das z.B. eine Addition atomar ist. Also während dieser Operation findet kein Wechsel des Threads statt. Normalerweise macht man das so das man eine Wrapper-Klasse z.B. um einen Integer baut mit Methoden die die gewünschten Methoden anbieten. Intern wird dann z.B. einfach ein Mutex genutzt.
Beispiel: AtomicInteger in Java

Was ein SpinLock ist weiß ich ehrlich gesagt nicht. Ich kenne nur noch Semaphoren. Semaphoren sind letztlich so eine Art Mutex mit Zähler. So können mehrere Threads einen Lock erhalten. Ist recht praktisch wenn man z.B. einen Wert nur lesen möchte aber nicht schreiben. Auch kann man z.B. die Anzahl der Zugriffe beschränken, etwa nur 5 parallele Zugriffe zulassen.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jan 25, 2011 14:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Selbst implementieren würde ich so etwas auch nicht wollen.

Unter Atomare Operationen verstehe ich allerdings etwas leicht anderes. Und zwar bezeichnet das Operationen die so klein sind, dass diese nicht unterbrochen werden. Als Beispiel (Delphi) das Setzen oder Rechnen mit Integern. Auf CPU Ebene betrachtet ist das reine Setzen/Addieren nur ein CPU Befehl. Bei Int64 ist das allerdings nicht atomar, da Int64 in 32 Bit Programmen mit mehreren Rechenschritten berechnet werden müssen. Dabei muss man aber auch bedenken, dass man in einer Hochsprache sehr schnell mehrere Operationen ausführen kann ohne wirklich aktiv mitzubekommen. Dann sind diese Operation sehr schnell nicht mehr atomar.

SpinLock kenne ich so vom Begriff her auch nicht. Wobei ich auch gerade mal nachgelesen habe und festgestellt, dass für mich nur der Begriff wirklich neu ist (Erinnert mich ein wenig an Bullshit-Bingo). Würde aber behaupten, dass man das nur verwenden sollte, wenn es wirklich auf jeden noch so kleinen Rechenzyklus ankommt und man wirklich nur sehr sehr kurz locken muss. Wenn man zu viele Stellen hat die darauf warten müssen verschwendet man zu viel Zeit. Die Anzahl der Threads und CPU Kernen ist dabei ausschlaggebend. Bei Wikipedia wurde allerdings auch die Wechselwirkung des Caches und sich überlappender Speicherbereiche auf Mehrkern CPUs etwas außer acht gelassen. Wenn zwei CPUs gleichzeitig sehr oft auf den gleichen Speicherblock schreibend zugreifen, dann muss der oft zwischen den CPUs hin und her verschoben werden. Was im Extrem sehr viel Zeit kosten kann.

Im Endeffekt arbeiten CriticalSections, Mutexe und Semaphoren (Schutz von X Resourcen) aber alle stark ähnlich. Verhindern, dass ein Zweiter auf einen geschützten Bereich zugreifen kann. Was es noch gibt sind Events. Damit kannst du ein Handle erstellen. Jemand anderes kann warten bis ein Signal an dieses Handle gesendet wird. Da ist dann auch einstellbar ob sich das Handle dann sofort selbst wieder zurücksetzt oder ob man das manuell zurücksetzen muss. Mithilfe eines Namens ist das auch prozessübergreifend gültig.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jan 25, 2011 16:15 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Eine Addition ist nicht notwendigerweise atomar. In einer Hochsprache kann das verdammt schnell gehen ohne das man es mitbekommt. Wenn beispielsweise die Variable erst noch aus dem RAM oder Cache geholt werden muss ist das schon nicht mehr atomar. Und bei einem Thread-Wechsel kannst du eigentlich davon ausgehen da der Register-Inhalt zum Thread gehört ;)
(Achtung: Halbwissen, habe hier nicht wirklich Ahnung, korrigiere mich jemand wenn ich Unsinn rede...)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jan 25, 2011 17:04 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Das stimmt wohl. Es kommt da glaube ich auch darauf an was man betrachtet. Macht man nur so etwas wie Variable + fixer Wert, dann ist es wohl sehr wahrscheinlich nur eine CPU Anweisung und somit atomar. Bei Zwei Variablen ist es aber so, dass zu erst die eine Variable in ein Register geladen werden muss und erst dann addiert werden kann. Das sind zwar zwei Befehle (die könnten unterbrochen werden) aber das reine Addieren (der Schreibvorgang) ist wieder atomar. Entsprechend werden nie halbgeschriebene Daten (halbaddierte Werte) im Speicher existieren. Da hat aber in jedem Fall der Kompiler noch ein Wörtchen mitzureden. Der Sinn bei Hochsprachen ist ja eben, dass man sich um das Darunter nicht mehr kümmern muss. Entsprechend kann der Kompiler an dem Code durchaus noch was drehen. Ist also alles nur ein sehr dünner Grad auf den man sich nicht blind verlassen kann. Auf Assemblerebene gibt es aber noch ganz andere Sachen. Conditional Move (CMOV) zum Beispiel.

Das mit dem RAM und dem Cache sollte meines Wissens nach eher weniger Probleme machen. Hab das schon mal am eigenen Leib mitbekommen dürfen, dass die Synchronisierung zwischen den CPUs ganz gut funktioniert. Jede CPU kann die Speicherbereiche lesend in den Cache laden. Sobald eine CPU schreiben will wird ein Signal über den Bus geschickt und der Speicher zum Schreiben für die CPU geblockt. Sollte eine andere CPU diesen Block zum Schreiben inne haben so wird er zurückgeschrieben und überall im Cache als ungültig markiert. Ungültig damit bei erneuten lesenden Zugriffen die Daten neu angefordert werden (um aktuellere Daten zu bekommen). Erst anschließend darf die zweite CPU dort hinein schreiben. Solange muss sie warten. Im Falle von Hyperthreading kann dann ein anderer Hardwarethread auf der wartenden CPU ausgeführt werden. Wenn es geht sollte man es vermeiden aus mehreren Thread auf ein und die selben Speicherblöcke dauerhaft lesend und schreibend zuzugreifen. Speicherblöcke haben da meiste eine Größe von 64 Bytes. Also nicht nur ein und die selbe Adresse sondern noch etwas Speicher herum.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 26, 2011 11:51 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Mutex, CriticialSection und da gibs noch ein paar Buzzwords die exakt das gleiche beschreiben, den alt bekannten Mutex zum verwalten einer Ressource.
SpinLock ist eine bestimmte Implementierung(für Prozesse,atomare Operationen) von einen sperrmechanismus gehört zur Kategorie Mutex und Co. .

Was macht nun ein Mutex ? Ziemlich einfach, ein Mutex ist eine einzelnes Speicher Register, welches verschiedene Zustände repräsentiert.
0=hey du bist der einzige der die Ressource gerade nutzen will.
1...=die ressource wird gerade von jemanden benutzt, du musst warten.
Hier gibt es unterschiedliche implementierung, wobei die übliche ein counter ist, welcher für jeden Lock versuch um 1 erhöht und der Thread merkt sich diese Nummer. Sollte ein aktiver Thread unlock machen, dann wird das Register vom Mutex um 1 erhöht und der Thread, der diese Nummer vom Counter vorher bekommen hat, darf nun locken. Damit entsteht ein FIFO. Wie der Thread raus bekommt, dass sich der Mutex geändert hat ist unterschiedlich implementiert, mal mit Atomare Operatoren, mal mit Condition oder über Interrupts.

AtomicOperations, sind nun schon ne hand voll Jahre bekannt und werden die alten Verfahren stück für stück ablösen, da diese viele Vorteile haben.
AOs sind Operationen, wie +,-,... aber auch AddElement, FindElement, RemoveElement und so weiter. Die Arithmetischen AOs werden von der CPU implementiert und sind auch auf recht alten CPU's verfügbar aber die Frage ist welche ^^. MS bietet eine vollständige API für Windows an und VSC++ sowie GCC können den CPU Befehlssatz. Der große unterschied zwischen AOs und z.B. einem Mutex ist folgender.
Der Mutex muss erst lock, auf interrupt warten, mit ressource arbeiten, unlock und eine AO kopiert den aktuellen Wert, führt die operation aus, vergleicht das ergebnis mit dem aktuellen Wert und ist es nicht gleich, dann von vorne, bis es gleich ist.
Also AOs laufen in der Loop und man muss auch noch dem Compiler sagen, dass diese funktionen alle speicheraddressen direkt lesen soll und nicht die Daten in die Register zwischen speichert(sonnst hat man nie die aktuellen Speicherwerte).
AOs haben keine Threadswitches zufolge, wie es bei Mutex und co oft passiert, die Praxis hat gezeigt, dass das mehrfach durchlaufen einer AO um ein vielfaches kostengünstiger ist als das alte Lock/Unlock verfahren. AO, sind per software implementierbar(unter windows ne gute idee, unter linux verliert man eventuell performance), einfacher zu verwenden, da man keine extra variable für jede Ressource mit rum schleppt. Bei zu vielen Threads auf zu wenigen kernen bzw. nur einem performed es um welten besser als Mutex und co.
Nachteil, AOs sind nicht immer trivial zu implementieren, bei dynamischen Strukturen ist es echt schwer und teilweise aufwändig.
Das ist der Grund wieso ich bei Mutex geblieben bin ^^ zu wenig Zeit aber bisher die einzige Möglichkeit Platformunabhängig was an zu bieten.

Die Performanteste Mutex, Condition, Thread, Semaphore Bibliothek, die ich kenne, ist pthread.
Unter Windows gibt es seit Windows Vista eine neue API für Threading, welche um ein vielfaches schneller ist aber trotzdem nicht mit pthread auf Linux mit halten kann. Unter Linux hat man vor vielen Jahren die pthreads auf micro threads umgestellt(auch die Stackgröße geändert). Dies hatte Thread switches bis in den Nano Sekunden bereich zu folge(MS braucht zwischen Microsekunden bis 16ms). Es gibt eine pthread implementierung für Windows aber ich hab selber lieber die Windows API verwendet und das Verhalten beider Bibliotheken auf einem Nenner gebracht.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jan 26, 2011 23:05 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 03, 2002 15:08
Beiträge: 662
Wohnort: Hamburg
Programmiersprache: Java, C# (,PhP)
Auch wenn es sich auf Java bezieht, aber ich fand die Artikel damals sehr lesenswert.
http://www.angelikalanger.com/Articles/ ... eJava.html
Zu Threads und Idiomen ^^"

Kann sonst mal schauen ob die auf der Jahres-CD komplett drauf sind und zur Verfügung stellen.

_________________
(\__/)
(='.'=)
(")_(")


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 14 Queries | GZIP : On ]