2012-06-05 17 views
21

Was ist der Unterschied zwischen Zählen und binären Semaphor.Unterschied zwischen Zählen und binären Semaphoren

Was ich irgendwo gesehen habe, ist, dass beide N Prozesse steuern können, die für eine Ressource angefordert haben. Beide haben genommen und Freistaaten.

Gibt es Einschränkungen bezüglich der Anzahl der Ressourcen, die ein binärer Semaphor und ein Zähl-Semaphor schützen können?

Beide erlauben nur ein Prozess, eine Ressource zu einem Zeitpunkt, zu verwenden ...

Gibt es einen anderen Unterschied? Sind die oben genannten Eigenschaften korrekt?

+0

Ein guter Anwendungsfall für einen Zähl-Semaphor ist, wenn Sie nur nach mehreren abgeschlossenen Ereignissen fortfahren möchten. Zum Beispiel startet Ihr Programm 5 verschiedene asynchrone Datenbanklesevorgänge und initiiert sie, und sollte erst fortgesetzt werden, wenn alle 5 abgeschlossen sind. Sie würden den Semaphor zu Beginn jedes Lesevorgangs inkrementieren und sofort 'Semaphore == 0' blockieren. Nach Abschluss jedes Lesevorgangs dekrementieren Sie den Semaphor. Ihr Start wird nach Abschluss der Datenladung fortgesetzt. –

Antwort

25

Tatsächlich werden beide Typen verwendet, um den Zugriff auf eine freigegebene Ressource zu synchronisieren, unabhängig davon, ob die Entität, auf die zugegriffen wird, ein Prozess oder sogar ein Thread ist.

Der Unterschied ist wie folgt:

Binary Semaphore sind binär, sie nur zwei Werte haben kann; ein, um anzuzeigen, dass ein Prozess/Thread im kritischen Abschnitt ist (Code, der auf die freigegebene Ressource zugreift), und andere warten sollten, während der andere angibt, dass der kritische Abschnitt frei ist.

Auf der anderen Seite, zählen Semaphoren mehr als zwei Werte, sie können jeden gewünschten Wert haben. Der Maximalwert X, den sie annehmen, ermöglicht X-Prozessen/Threads den gleichzeitigen Zugriff auf die gemeinsam genutzte Ressource.

Weitere Informationen finden Sie unter diesem Link.
http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:semaphores_mutexes

EDIT
Der maximale Wert, der ein Zählen Semaphore nehmen kann die Anzahl der Prozesse, die Sie zur gleichen Zeit in den kritischen Abschnitt ermöglichen wollen.
Vielleicht haben Sie wieder einen Fall, in dem Sie eine bestimmte Ressource ausschließen möchten, aber Sie wissen, dass diese Ressource von einer maximalen Anzahl von Prozessen (zB X) aufgerufen werden kann. Setzen Sie also einen Zähl-Semaphor mit dem Wert X.

Dies würde den X-Prozessen erlauben, gleichzeitig auf diese Ressource zuzugreifen; der Prozess X + 1 müsste jedoch warten, bis einer der Prozesse im kritischen Abschnitt herauskommt.

+3

Sir Sie sagten, dass die Prozesse die Ressource gleichzeitig verwenden können! Semaphore werden jedoch zum Implementieren des gegenseitigen Ausschlusses verwendet, da nur ein Prozess die Ressource gleichzeitig verwenden kann. Hab ich recht oder nicht. Was bedeutet der Maximalwert des Semaphors? –

+3

Gut, Semaphore zählen mehrere Prozesse gleichzeitig die gemeinsamen Ressourcen zu verwenden. Manchmal möchten Sie nur zwei Prozesse im kritischen Abschnitt gleichzeitig zulassen, nicht mehr, aber nicht nur eins, weil zwei die Aufgabe ohne Fehler für die Logik Ihres Programms ausführen können. Ich kann jetzt nicht an ein Beispiel denken, aber das ist die Grundidee. – Fingolfin

+1

Danke, Sir, dass Sie das geklärt haben. Noch eine Frage. Haben die binären Semaphoren die Fähigkeit, mehreren Prozessen zu erlauben, die Ressource gleichzeitig zu benutzen? ODER sie können nur einen Prozess auf einmal zulassen –

8

Es gibt zwei wesentliche Konzepte zum Erstellen von konkurrierenden Programmen - Synchronisierung und wechselseitiger Ausschluss. Wir werden sehen, wie diese beiden Arten von Sperren (Semaphore sind im allgemeinen eine Art Sperrmechanismus) uns helfen, Synchronisation und gegenseitigen Ausschluss zu erreichen.

Ein Semaphor besteht aus zwei Teilen: einem Zähler und einer Liste von Aufgaben, die auf den Zugriff auf eine bestimmte Ressource warten. Ein Semaphor führt zwei Operationen aus: Warten (P) [das ist wie das Erlangen einer Sperre] und Freigabe (V) [ähnlich dem Freigeben einer Sperre] - dies sind die einzigen zwei Operationen, die man an einem Semaphor ausführen kann. In einem binären Semaphor geht der Zähler logisch zwischen 0 und 1. Sie können sich vorstellen, dass er ähnlich einer Sperre mit zwei Werten ist: offen/geschlossen. Ein Zählsemaphor hat mehrere Werte für die Zählung.

Was wichtig zu verstehen ist, ist, dass der Semaphorzähler die Anzahl der Aufgaben verfolgt, die nicht blockiert werden müssen, d. H. Sie können Fortschritte machen. Aufgaben blockieren und fügen sich nur dann zur Liste des Semaphors hinzu, wenn der Zähler Null ist. Daher wird eine Aufgabe in der P() - Routine zur Liste hinzugefügt, wenn sie nicht fortgeführt werden kann, und mit der V() - Routine "befreit".

Nun ist es ziemlich offensichtlich zu sehen, wie binäre Semaphore verwendet werden können, um Synchronisation und gegenseitigen Ausschluss zu lösen - sie sind im Wesentlichen Sperren.

ex. Synchronisation:

thread A{ 
semaphore &s; //locks/semaphores are passed by reference! think about why this is so. 
A(semaphore &s): s(s){} //constructor 
foo(){ 
... 
s.P(); 
;// some block of code B2 
... 
} 

//thread B{ 
semaphore &s; 
B(semaphore &s): s(s){} //constructor 
foo(){ 
... 
... 
// some block of code B1 
s.V(); 
.. 
} 

main(){ 
semaphore s(0); // we start the semaphore at 0 (closed) 
A a(s); 
B b(s); 
} 

In dem obigen Beispiel kann B2 nur ausführen nach B1 Ausführung beendet hat. Angenommen, Thread A kommt zuerst - ruft sem.P() ab und wartet, da der Zähler 0 (geschlossen) ist. Thread B kommt, beendet B1 und gibt dann Thread A frei - der dann B2 vervollständigt. So erreichen wir die Synchronisation.

Nun wollen sie mit einer binären Semaphore bei mutual exclusion aussehen:

thread mutual_ex{ 
semaphore &s; 
mutual_ex(semaphore &s): s(s){} //constructor 
foo(){ 
... 
s.P(); 
//critical section 
s.V(); 
... 
... 
s.P(); 
//critical section 
s.V(); 
... 

} 

main(){ 
semaphore s(1); 
mutual_ex m1(s); 
mutual_ex m2(s); 
} 

Die gegenseitige Ausgrenzung ist auch ganz einfach - m1 und m2 in dem kritischen Abschnitt in der gleichen Zeit nicht eingeben. Daher verwendet jeder Thread den gleichen Semaphor, um einen gegenseitigen Ausschluss für seine zwei kritischen Abschnitte bereitzustellen. Ist es nun möglich, eine größere Parallelität zu haben? Hängt von den kritischen Abschnitten ab. (Denken Sie darüber nach, wie sonst könnte man Semaphore verwenden gegenseitigen Ausschluss zu erreichen .. Hinweis: Muss ich unbedingt nur ein Semaphore benutzen?)

Counting Semaphore: Eine Semaphore mit mehr als einem Wert. Schauen wir uns an, was das bedeutet - ein Schloss mit mehr als einen Wert? So offen, geschlossen und ... hmm. Welchen Nutzen hat eine mehrstufige Sperre für wechselseitigen Ausschluss oder Synchronisation?

Lassen Sie uns die einfachere der beiden nehmen:

Synchronisation eine Zählung Semaphore mit: Lasst uns sagen, Sie haben drei Aufgaben - # 1 und 2, die Sie nach dem 3. ausgeführt möchten, wie Sie Ihre Synchronisation entwerfen würde?

thread t1{ 
... 
s.P(); 
//block of code B1 

thread t2{ 
... 
s.P(); 
//block of code B2 

thread t3{ 
... 
//block of code B3 
s.V(); 
s.V(); 
} 

Also, wenn Ihr Semaphore geschlossen beginnt, können Sie diesen T1- und T2-Block sicherzustellen, auf die Semaphore der Liste hinzugefügt. Dann kommt alles Wichtige t3, beendet sein Geschäft und befreit t1 und t2. In welcher Reihenfolge werden sie freigegeben? Hängt von der Implementierung der Semaphor-Liste ab. Könnte FIFO sein, könnte eine bestimmte Priorität, etc. (Hinweis: darüber nachdenken, wie Sie Ihre P und V anordnen würden; s, wenn Sie T1 und T2 wollten in einer bestimmten Reihenfolge ausgeführt werden, und wenn Sie sind von der Umsetzung des Semaphore nicht bekannt)

(Finden Sie heraus,: Was passiert, wenn die Zahl der V geschieht, ist größer als die Anzahl von P)

Mutual Exclusion Zählen Semaphoren: ich würde Sie gerne Ihren eigenen Pseudo-Code für diese konstruieren (macht man die Dinge verstehen besser!) - aber das Grundkonzept ist das: ein Zähl-Semaphor von counter = N erlaubt N Aufgaben den freien Bereich frei zu betreten. Was das bedeutet ist, dass Sie N Aufgaben (oder Threads, wenn Sie möchten) den kritischen Abschnitt betreten, aber die N + 1te Aufgabe wird blockiert (geht auf unsere Lieblingsliste mit blockierten Aufgaben) und wird nur durchgelassen, wenn jemand V der Semaphor ist mindestens einmal. Also geht der Semaphor-Zähler, statt zwischen 0 und 1 zu schwingen, jetzt zwischen 0 und N, wodurch N Aufgaben frei ein- und ausgehen können und niemanden blockieren!

Nun, warum würden Sie solch ein bizarres Schloss brauchen?Ist das nicht der Sinn des gegenseitigen Ausschlusses, dass nicht mehr als ein Typ auf eine Ressource zugreifen darf? Denken. (Hint ... Sie müssen nicht immer nur eine-Laufwerk in Ihrem Computer, nicht wahr ...?)

zu denken: Ist mutual exclusion erreicht, indem eine Zählung mit Semaphore allein? Was ist, wenn Sie 10 Instanzen einer Ressource haben und 10 Threads (über den Zähl-Semaphor) hereinkommen und versuchen, die erste Instanz zu verwenden?

+0

Es ist überhaupt keine bizarre Sperre, wenn ein Thread blockiert, bis du einen gemeinsamen Speicher gesetzt hast und den Semaphor loslässt (zB String auf Hallo Welt setzen, dann Semaphor loslassen, er wird die Nachricht drucken und den Semaphor erneut blockieren) Sie benötigen einen Semaphor, um diesen Thread zu entsperren. Eine Sperre verhindert, dass Sie ihn entsperren, da er an den Sperrfaden gebunden ist. Soweit ich weiß, ist dies die Grundlage aller asynchronen Kommunikation und so ziemlich die einzige Möglichkeit, funktionale Programmiersprachen dazu zu bringen, einen Status zu erhalten, indem ein Thread/Prozess erstellt wird, der seinen Status abhängig von den empfangenen Nachrichten zyklisch ändert. – Dmitry

0

Der grundlegendste Unterschied zwischen Zählen und Binärsemaphore ist, dass:

  1. Binary Semaphore nicht Bounded Warte als nur eine Variable, die binären Wert halten verarbeiten kann. Counting semaphore Es kann bounded wait verarbeiten, da es eine Variable in eine Struktur mit einer Queue konvertiert hat.
  2. Strcuture-Implementierung Binär-Semaphor: int s;

    Counting Semaphore: Struct S { int s; Warteschlange q; }

das Zählen Semaphore Mit nun einmal verarbeiten gewann die CS (Critical Section) jetzt für den anderen zu warten, hat die CS zu bekommen, also nicht einen einzigen Prozess strave. Jeder Prozess erhält eine Chance für CS.

+0

warum binäre Semaphore int s haben müssen?es zählt immer 1, warum müssen wir einen Zählwert dafür verwenden? –