2017-04-12 8 views
0

Habe gerade ein Video auf Semaphoren gesehen und versucht zu graben für weitere Informationen. Nicht ganz sicher, wie ein Semaphor auf einer Baugruppenebene funktioniert.Nicht zu verstehen Semaphor auf niedrigem Niveau

P(s): 
    s = s - 1 
    if (s < 0) {wait on s} 

CRITICAL SECTION 

V(s): 
    s = s + 1 
    if(threads are waiting on s) {wake one} 

Ich verstehe, was das Konzept hinter dieser Funktion ist jedoch Ich habe Probleme, meinen Kopf diese um wickeln.

sagen S = 1 und Sie haben 2 Themen: Thema 1 und Faden 2

Thread One          Thread Two 
load s           load s 
subtract s,1         subtract s,1      
save s           save s 

Dann gibt es einen Kontextwechsel zwischen dem subtrahieren und die für beide Einstellung s auf 0 für beide speichern. Nicht beide Threads sehen s, wie 0 in den kritischen Abschnitt eintritt. Ich bin mir nicht sicher, wie ein Thread exklusiv wird, wenn es auf der Assembly-Ebene möglich ist, Kontextwechsel, so dass beide sehen können s = 0.

+0

Sie haben den Teil "Warten auf s" in Ihrer Aufschlüsselung vergessen. –

+0

Nicht sicher, was du meinst? Gibt es einen Mutex auf S? – train55255

+0

Nein, kein Mutex, sondern ein Semaphor. Es ist eine andere Art von Synchronisationsmechanismus, aber genau wie ein Mutex liefert er typischerweise effizientes * Blockieren *, d. H. Es interagiert mit dem OS-Scheduler. –

Antwort

2

Der Schlüssel ist, dass die Inkrement und Dekrement atomare Anweisungen in irgendeiner Weise verwenden. Innerhalb von x86 gibt es eine Form der add-Anweisung, die in Kombination mit dem Sperrpräfix die automatische Addition eines Speicherorts ermöglicht. Da es sich um einen einzelnen Befehl handelt, kann ein Kontextwechsel während seiner Ausführung nicht passieren, und das Sperrpräfix bedeutet, dass die CPU sicherstellt, dass während des Inkrements keine weiteren Zugriffe auftreten.

Wenn ein atomarer Zusatz nicht verfügbar ist, gibt es andere Optionen. Eine übliche ist eine atomare Vergleichs- und Tauschanweisung. Auf den meisten Systemen, die parallelen oder gleichzeitigen Code unterstützen, ist es eine Anweisung, die zwei Werte verwendet, eine alte und eine neue, und wenn die Speicherstelle der alten entspricht, legen Sie sie auf den neuen Wert fest. Dies kann in einer Schleife verwendet werden, um eine atomare Add umzusetzen:

l: 
load r0 s 
mov r1 r0 
add r0 -1 
cas s r1 r0 
jmpf l 

Dieser Wert lädt, subtrahiert dann 1 von einer Kopie des Wertes. wir versuchen dann, den niedrigeren Wert zu speichern, aber wenn es sich geändert hat, scheitern wir und beginnen erneut.

+0

Das ist perfekt, vielen Dank. Ich erinnere mich vage daran, dass mein Professor gesagt hat, dass die Instruktionen in der Vorlesung atomar sind, aber du hast das alles einfach aufgehoben und es direkt auf den Kopf geschlagen. Ich danke dir sehr! – train55255

+0

Ich wünschte, mein Prof würde noch einen Schritt weiter gehen, um noch ein wenig mehr in das niedrige Level zu graben, noch einmal vielen Dank. Würde dies jedoch niemals ineffizient werden? Sagen Sie, wenn es viele Kontextwechsel gibt, könnten Sie jemals in vier Anweisungen stecken bleiben, die versuchen, zu addieren oder zu subtrahieren? – train55255