2010-10-20 3 views
16

Ich habe gelesen auf Multithreading und freigegebenen Ressourcen zugreifen und eine der vielen (für mich) neue Konzepte ist die Mutex-Sperre. Was ich nicht herausfinden kann, ist, was tatsächlich passiert, wenn der Thread, der einen "kritischen Bereich" findet, gesperrt ist. Es sagt an vielen Stellen, dass der Thread "blockiert" wird, aber was bedeutet das? Ist es ausgesetzt und wird es fortgesetzt, wenn das Schloss angehoben wird? Oder wird es in der nächsten Iteration der "run loop" noch einmal versuchen? Der Grund, warum ich frage, ist, weil ich System geliefert Ereignisse (Maus, Tastatur, etc.) möchte, die (apparent) auf dem Haupt-Thread geliefert werden, um in einem ganz bestimmten Teil in der Lauf-Schleife behandelt werden von meinem sekundären Thread. Also, welches Ereignis auch immer geliefert wird, ich stehe in meiner eigenen Datenstruktur Schlange. Offensichtlich benötigt die Datenstruktur eine Mutex-Sperre, da sie von beiden Threads modifiziert wird. Das fehlende Puzzle-Stück ist: Was passiert, wenn ein Ereignis in einer Funktion im Haupt-Thread geliefert wird, ich möchte es in die Warteschlange stellen, aber die Warteschlange ist gesperrt? Wird der Hauptthread ausgesetzt oder springt er einfach über den gesperrten Bereich und verliert seinen Gültigkeitsbereich (Verlust des Ereignisses)?Mutex-Sperre: Was bedeutet "blockieren"?

Antwort

11

Blockiert bedeutet, dass die Ausführung dort stecken bleibt; Im Allgemeinen wird der Thread vom System in den Ruhezustand versetzt und der Prozessor einem anderen Thread zugeführt. Wenn ein Thread blockiert wird und versucht wird, einen Mutex zu erhalten, wird die Ausführung fortgesetzt, wenn der Mutex freigegeben wird. Der Thread wird jedoch möglicherweise erneut blockiert, wenn ein anderer Thread den Mutex vorwegnimmt.

Es gibt im Allgemeinen eine Try-Lock-Operation, die den Mutex wenn möglich anfasst und andernfalls einen Fehler zurückgibt. Aber Sie müssen das aktuelle Ereignis schließlich in diese Warteschlange verschieben. Wenn Sie die Ereignisse in den Thread verschieben, in dem sie behandelt werden, reagiert die Anwendung nicht mehr.

Eine Warteschlange ist eigentlich ein Fall, in dem man ohne Mutex davonkommen kann. Zum Beispiel bietet Mac OS X (und möglicherweise auch iOS) die Funktionen OSAtomicEnqueue() und OSAtomicDequeue() (siehe man atomic oder <libkern/OSAtomic.h>), die prozessorspezifische atomare Operationen ausnutzen, um die Verwendung einer Sperre zu vermeiden.

Aber, warum nicht nur die Ereignisse im Hauptthread als Teil der Hauptlaufschleife verarbeiten?

+0

Die Hauptlaufschleife ist nicht das, was die Anwendung antreibt. Ich bin auf Mac OSX und benutze einen CVDisplayLink, der effektiv einen separaten Thread (hohe Priorität) hervorbringt, der wiederum meine Laufschleife antreibt. Ereignisse, so wie ich es verstehe, werden auf dem Hauptthread geliefert, so dass die Synchronisation in Ordnung scheint. – zmippie

1

Blockieren bedeutet genau das. Es ist blockiert. Es wird nicht fortgesetzt, bis es möglich ist. Sie sagen nicht, welche Sprache Sie verwenden, aber die meisten Sprachen/Bibliotheken haben Sperrobjekte, bei denen Sie versuchen können, die Sperre zu übernehmen und dann etwas anderes zu tun, je nachdem, ob Sie erfolgreich waren oder nicht.

Aber in Java synchronisierten Blöcken zum Beispiel wird Ihr Thread stehen bleiben, bis es den Monitor (Mutex, Sperre) erwerben kann. Die Schnittstelle java.util.concurrent.locks.Lock beschreibt Verriegelungsobjekte, die hinsichtlich der Erfassung von Sperren flexibler sind.

6

Der einfachste Weg, um daran zu denken ist, dass der blockierte Thread in einen Wartezustand versetzt wird, bis der Mutex vom Thread freigegeben wird, der ihn hält. An diesem Punkt "weckt" das Betriebssystem einen der Threads, die auf den Mutex warten, und lasst ihn erfassen und fortfahren. Es ist so, als ob das Betriebssystem den blockierten Thread einfach in ein Regal legt, bis er das hat, was er braucht, um fortzufahren. Bis das OS den Thread aus dem Regal nimmt, tut es nichts. Die genaue Implementierung - welcher Thread als nächstes kommt, ob sie alle aufgeweckt werden oder in die Warteschlange gestellt werden - hängt von Ihrem Betriebssystem ab und welcher Sprache/Framework Sie verwenden.

+0

Was genau ist der Unterschied in blockiert oder warten, sind sie das gleiche? – Celeritas

0

Zu spät zu beantworten, aber ich kann das Verständnis erleichtern. Ich spreche mehr von der Implementierungsperspektive als von theoretischen Texten.

Das Wort "Blockierung" ist eine Art technischer Homonym.Menschen können es für schlafen oder nur warten verwenden. Der Begriff muss im Zusammenhang mit der Verwendung verstanden werden.

Sperrmittel Waiting - Angenommen, auf einem SMP-System ein Thread A will eine spinlock von einem anderen Thread B. Einer der Mechanismen, gehalten erwerben ist Vorkaufsrecht zu deaktivieren und hält auf dem Prozessor Spinnen, es sei denn B wird es. Ein anderer Mechanismus, wahrscheinlich ein effizienter Mechanismus, besteht darin, anderen Threads zu erlauben, den Prozessor zu verwenden, falls B es nicht in einfachen Versuchen bekommt. Daher terminieren wir Thread B (wenn die Vorbelegung aktiviert ist) und geben den Prozessor an einen anderen Thread C weiter. In diesem Fall wartet der Thread B nur in der Warteschlange des Schedulers und kehrt dann zurück. Verstehen Sie, dass B nicht gerade schläft, sondern eher passiv statt beschäftigt wartet und Prozessorzyklen abwartet. Auf BSD- und Solaris-Systemen gibt es Datenstrukturen wie Drehkreuze, um diese Situation zu implementieren.

Sperrmittel Sleeping - Wenn der Faden B statt Systemaufruf wie read() Wartedaten von Netzwerk-Socket gemacht hatte, kann es nicht weitergehen, bis er es bekommt. Daher verwenden einige Texte die Begriffsblockierung zufällig als "... blockiert für E/A" oder "... im blockierenden Systemaufruf". Tatsächlich schläft Thread B eher. Es gibt spezifische Datenstrukturen, die als Warteschlangen bekannt sind - ähnlich wie luxuriöse Warteräume auf Flughäfen :-). Der Thread wird aufgeweckt, wenn das Betriebssystem die Verfügbarkeit von Daten erkennt, ähnlich wie eine Begleitperson des Warteraums.