it-swarm-eu.dev

Unterschied zwischen binärem Semaphor und Mutex

Gibt es einen Unterschied zwischen einem binären Semaphor und einem Mutex oder sind sie im Wesentlichen gleich?

767
Nitin

Sie sind NICHT dasselbe. Sie werden für verschiedene Zwecke verwendet!
Obwohl beide Arten von Semaphoren einen vollständigen/leeren Zustand haben und dieselbe API verwenden, ist ihre Verwendung sehr unterschiedlich.

Gegenseitige Ausschlusssemaphoren
Semaphoren für gegenseitigen Ausschluss werden zum Schutz gemeinsam genutzter Ressourcen (Datenstruktur, Datei usw.) verwendet.

Ein Mutex-Semaphor gehört der Task, die es übernimmt. Wenn Task B versucht, einen von Task A gehaltenen Mutex zu semGeben, gibt der Aufruf von Task B einen Fehler zurück und schlägt fehl.

Mutexe verwenden immer die folgende Reihenfolge:

 - SemTake 
 - Kritischer Abschnitt 
 - SemGive

Hier ist ein einfaches Beispiel:

 Thread A Thread B 
 Mutex nehmen 
 Zugangsdaten 
 ... Mutex nehmen <== Blockiert 
 ... 
 Mutex Zugangsdaten geben <== Unblocks 
 ... 
 Mutex geben 

Binärsemaphor
Binary Semaphore adressieren eine ganz andere Frage:

  • Task B wartet auf das Eintreten eines Ereignisses (z. B. Auslösen eines Sensors).
  • Sensorauslösungen und eine Interrupt-Serviceroutine werden ausgeführt. Es muss eine Aufgabe der Reise mitteilen.
  • Task B sollte ausgeführt werden und geeignete Maßnahmen für die Sensorauslösung ergreifen. Dann geh zurück zum Warten.

   Task A                      Task B
   ...                         Take BinSemaphore   <== wait for something
   Do Something Noteworthy
   Give BinSemaphore           do something    <== unblocks

Beachten Sie, dass es mit einem binären Semaphor in Ordnung ist, dass B das Semaphor nimmt und A es gibt.
Wiederum schützt ein binäres Semaphor eine Ressource NICHT vor dem Zugriff. Das Geben und Nehmen eines Semaphors ist grundsätzlich entkoppelt.
Normalerweise macht es für dieselbe Aufgabe wenig Sinn, ein und dasselbe binäre Semaphor zu geben und zu nehmen.

661
Benoit

Das Toilettenbeispiel ist eine unterhaltsame Analogie:

Mutex:

Ist ein Schlüssel zu einer Toilette. Eine Person kann den Schlüssel haben - die Toilette besetzen - zu der Zeit. Wenn der Vorgang abgeschlossen ist, gibt die Person den Schlüssel an die nächste Person in der Warteschlange weiter (gibt ihn frei).

Offiziell: "Mutexe werden normalerweise verwendet, um den Zugriff auf einen Teil des wiedereintretenden Codes zu serialisieren, der nicht gleichzeitig von mehr als einem Thread ausgeführt werden kann. Ein Mutex-Objekt lässt nur einen Thread in einen kontrollierten Abschnitt zu und erzwingt andere Threads, die versuchen, Zugriff auf diesen zu erhalten diesem Abschnitt warten, bis der erste Thread diesen Abschnitt verlassen hat. " Ref: Symbian Developer Library

(Ein Mutex ist wirklich ein Semaphor mit dem Wert 1.)

Semaphor:

Ist die Anzahl der kostenlosen identischen Toilettenschlüssel. Angenommen, wir haben vier Toiletten mit identischen Schlössern und Schlüsseln. Die Semaphorenzählung - die Anzahl der Schlüssel - wird zu Beginn auf 4 gesetzt (alle vier Toiletten sind frei), dann wird der Zählwert verringert, wenn Personen hereinkommen. Wenn alle Toiletten voll sind, d. H. es sind keine freien Schlüssel mehr vorhanden, die Semaphorenzahl ist 0. Wenn nun Gl. Eine Person verlässt die Toilette, das Semaphor wird auf 1 erhöht (ein freier Schlüssel) und an die nächste Person in der Warteschlange weitergegeben.

Offiziell: "Ein Semaphor beschränkt die Anzahl gleichzeitiger Benutzer einer freigegebenen Ressource auf eine maximale Anzahl. Threads können den Zugriff auf die Ressource anfordern (Dekrementierung des Semaphors) und signalisieren, dass sie die Ressource nicht mehr verwenden (Inkrementierung des Semaphors). " Ref: Symbian Developer Library

431
dlinsin

Mutex kann nur von einem Thread freigegeben werden, der es erworben hat, während Semaphore von jedem anderen Thread (oder Prozess) signalisiert werden können. Semaphore eignen sich daher besser für einige Synchronisationsprobleme wie Producer-Consumer.

Binäre Semaphore ähneln unter Windows eher Ereignisobjekten als Mutexen.

418

Schöne Artikel zum Thema:

Aus Teil 2:

Der Mutex ähnelt den Prinzipien des binären Semaphors mit einem wesentlichen Unterschied: dem Prinzip des Eigentums. Eigentum ist das einfache Konzept, dass eine Aufgabe, wenn sie einen Mutex sperrt (erwirbt), ihn nur entsperren (freigeben) kann. Wenn eine Task versucht, einen Mutex zu entsperren, der nicht gesperrt ist (und somit keinen besitzt), tritt eine Fehlerbedingung auf, und der Mutex wird vor allem nicht entsperrt. Wenn das Objekt für den gegenseitigen Ausschluss kein Eigentum hat, ist es kein Mutex, unabhängig davon, wie es genannt wird.

142
teki

Da keine der obigen Antworten die Verwirrung beseitigt, ist hier eine, die meine Verwirrung beseitigt.

Genau genommen ist ein Mutex ein Sperrmechanismus , mit dem der Zugriff auf eine Ressource synchronisiert wird. Nur eine Task (kann ein Thread oder ein Prozess sein, der auf der Betriebssystemabstraktion basiert) kann den Mutex abrufen. Dies bedeutet, dass mit Mutex Besitz verbunden ist und nur der Besitzer die Sperre aufheben kann (Mutex).

Semaphor ist Signalmechanismus (Signalart "Ich bin fertig, du kannst weitermachen"). Wenn Sie beispielsweise Musiktitel auf Ihrem Mobiltelefon hören (als eine Aufgabe annehmen) und gleichzeitig Ihr Freund Sie anruft, wird ein Interrupt ausgelöst, bei dem eine Interrupt-Serviceroutine (ISR) die Anrufbearbeitungsaufgabe zum Aufwecken veranlasst .

Quelle: http://www.geeksforgeeks.org/mutex-vs-semaphore/

94
Hemant

Ihre Synchronisationssemantik ist sehr unterschiedlich:

  • mutexe ermöglichen die Serialisierung des Zugriffs auf eine bestimmte Ressource, dh, mehrere Threads warten nacheinander auf eine Sperre, und wie bereits erwähnt, besitzt der Thread die Sperre , bis dies abgeschlossen ist: nur dieser bestimmte Thread kann es entsperren.
  • ein binäres Semaphor ist ein Zähler mit den Werten 0 und 1: Eine Task blockiert ihn, bis eine any Task einen sem_post ausführt. Das Semaphor gibt an, dass eine Ressource verfügbar ist, und stellt den Mechanismus zum Warten bereit, bis signalisiert wird, dass sie verfügbar ist.

Als solches kann man einen Mutex als Token sehen, das von Aufgabe zu Aufgabe weitergereicht wird, und ein Semaphor als Ampel (es signalisiert jemandem, dass es weitergehen kann).

39
ppi
  • Ein Mutex wird per Definition verwendet, um den Zugriff auf einen Teil des wiedereintretenden Codes zu serialisieren, der nicht von mehr als einem Thread gleichzeitig ausgeführt werden kann.

  • Ein Semaphor begrenzt per Definition die Anzahl der gleichzeitigen Benutzer einer gemeinsam genutzten Ressource auf eine maximale Anzahl

  • Ein Semaphor kann ein Mutex sein, aber ein Mutex kann niemals ein Semaphor sein. Dies bedeutet einfach, dass ein binäres Semaphor als Mutex verwendet werden kann, ein Mutex jedoch niemals die Funktionalität eines Semaphors aufweisen kann.

  • Sowohl Semaphore als auch Mutex (mindestens der neueste Kernel) sind nicht rekursiver Natur.
  • Niemand besitzt Semaphore, während Mutex Eigentum ist und der Eigentümer dafür verantwortlich gemacht wird. Dies ist eine wichtige Unterscheidung aus Sicht des Debuggens.
  • Im Fall von Mutex ist der Thread, der den Mutex besitzt, dafür verantwortlich, ihn freizugeben. Bei Semaphoren ist diese Bedingung jedoch nicht erforderlich. Jeder andere Thread kann signalisieren, dass das Semaphor mithilfe von s m p s (function.e_ot) freigegeben wird.

  • Ein weiterer Unterschied, der für Entwickler von Bedeutung ist, besteht darin, dass Semaphore systemweit sind und in Form von Dateien auf dem Dateisystem verbleiben, sofern nichts anderes bereinigt wird. Mutex ist prozessweit und wird automatisch bereinigt, wenn ein Prozess beendet wird.

  • Die Art der Semaphoren ermöglicht es, sie beim Synchronisieren von verwandten und nicht verwandten Prozessen sowie zwischen Threads zu verwenden. Mutex kann nur zum Synchronisieren zwischen Threads und höchstens zwischen verwandten Prozessen verwendet werden (die pthread-Implementierung des neuesten Kernels bietet eine Funktion, mit der Mutex zwischen verwandten Prozessen verwendet werden kann).
  • Laut der Kernel-Dokumentation sind Mutex im Vergleich zu Semaphoren leichter. Dies bedeutet, dass ein Programm mit Semaphornutzung einen höheren Speicherbedarf aufweist als ein Programm mit Mutex.
  • Aus der Sicht der Nutzung weist Mutex im Vergleich zu Semaphoren eine einfachere Semantik auf.
38
Varun Chhangani

Auf theoretischer Ebene unterscheiden sie sich semantisch nicht. Sie können einen Mutex mit Semaphoren implementieren oder umgekehrt (siehe hier für ein Beispiel). In der Praxis ist die Implementierung unterschiedlich und sie bieten geringfügig unterschiedliche Dienste an.

Der praktische Unterschied (in Bezug auf die sie umgebenden Systemdienste) besteht darin, dass die Implementierung eines Mutex auf einen leichteren Synchronisationsmechanismus abzielt. Im Oracle-Sprachgebrauch werden Mutexe als Latches und Semaphoren als Waits bezeichnet.

Auf der untersten Ebene verwenden sie eine Art atomaren Test und Set Mechanismus. Dies liest den aktuellen Wert eines Speicherorts, berechnet eine Art von Bedingung und schreibt einen Wert an diesem Ort in einen einzelnen Befehl, der nicht unterbrochen werden kann . Dies bedeutet, dass Sie ein Mutex erwerben und testen können, ob es vor Ihnen jemand anderes hatte.

Eine typische Mutex-Implementierung besteht aus einem Prozess oder Thread, der die Anweisung test-and-set ausführt und bewertet, ob der Mutex durch irgendetwas anderes festgelegt wurde. Ein entscheidender Punkt hierbei ist, dass es keine Interaktion mit Scheduler gibt, sodass wir keine Ahnung haben (und es ist uns egal), wer die Sperre gesetzt hat. Dann geben wir entweder unsere Zeitscheibe auf und versuchen es erneut, wenn die Aufgabe neu geplant wird, oder führen ein Spin-Lock aus. Ein Spinlock ist ein Algorithmus wie:

Count down from 5000:
     i. Execute the test-and-set instruction
    ii. If the mutex is clear, we have acquired it in the previous instruction 
        so we can exit the loop
   iii. When we get to zero, give up our time slice.

Wenn wir unseren geschützten Code (bekannt als kritischer Abschnitt ) ausgeführt haben, setzen wir einfach den Mutex-Wert auf Null oder was auch immer 'clear' bedeutet. Wenn mehrere Tasks versuchen, den Mutex abzurufen, erhält der nächste Task, der nach der Freigabe des Mutex geplant wird, Zugriff auf die Ressource. Normalerweise verwenden Sie Mutexe, um eine synchronisierte Ressource zu steuern, bei der ein exklusiver Zugriff nur für sehr kurze Zeiträume erforderlich ist, normalerweise, um eine Aktualisierung einer gemeinsam genutzten Datenstruktur durchzuführen.

Ein Semaphor ist eine synchronisierte Datenstruktur (in der Regel unter Verwendung eines Mutex) mit einer Anzahl und einigen Systemaufruf-Wrappern, die mit dem Scheduler ein bisschen tiefer interagieren als die Mutex-Bibliotheken. Semaphoren werden inkrementiert und dekrementiert und zum Blockieren von Aufgaben verwendet, bis etwas anderes fertig ist. Ein einfaches Beispiel hierfür finden Sie unter Producer/Consumer Problem . Semaphore werden auf einen bestimmten Wert initialisiert - ein binäres Semaphor ist nur ein Sonderfall, in dem das Semaphor auf 1 initialisiert wird. Durch das Posten auf ein Semaphor wird ein Warteprozess aufgeweckt.

Ein grundlegender Semaphor-Algorithmus sieht folgendermaßen aus:

(somewhere in the program startup)
Initialise the semaphore to its start-up value.

Acquiring a semaphore
   i. (synchronised) Attempt to decrement the semaphore value
  ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.

Posting a semaphore
   i. (synchronised) Increment the semaphore value
  ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.  
 iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.

Im Fall eines binären Semaphors besteht der wesentliche praktische Unterschied zwischen den beiden in der Art der Systemdienste, die die tatsächliche Datenstruktur umgeben.

EDIT: Wie evan zu Recht bemerkt hat, verlangsamen Spinlocks einen einzelnen Prozessor. Sie würden einen Spinlock nur für eine Multiprozessor-Box verwenden, da der Prozess, der den Mutex enthält, ihn auf einem einzelnen Prozessor niemals zurücksetzt, während eine andere Task ausgeführt wird. Spinlocks sind nur bei Multiprozessor-Architekturen nützlich.

Obwohl Mutex und Semaphore als Synchronisationsprimitive verwendet werden, gibt es einen großen Unterschied zwischen ihnen. Im Fall von Mutex kann nur der Thread, der den Mutex gesperrt oder erworben hat, ihn entsperren. Im Fall eines Semaphors kann ein Thread, der auf ein Semaphor wartet, durch einen anderen Thread signalisiert werden. Einige Betriebssysteme unterstützen die Verwendung von Mutex und Semaphoren zwischen Prozessen. In der Regel wird die Verwendung im gemeinsam genutzten Speicher erstellt.

18
Praveen_Shukla

Mutex: Angenommen, wir haben einen kritischen Abschnitt, auf den der Thread T1 zugreifen möchte, dann folgen die folgenden Schritte. T1:

  1. Sperren
  2. Kritischen Abschnitt verwenden
  3. Freischalten

Binärsemaphor: Es basiert auf der Signalisierung von Warten und Signalisieren. Warte (n) Verringere den "s" -Wert um eins. Normalerweise wird der "s" -Wert mit dem Wert "1" initialisiert, die Signale erhöhen den "s" -Wert um eins. Wenn der Wert "s" 1 ist, bedeutet dies, dass kein kritischer Abschnitt verwendet wird. Wenn der Wert 0 ist, bedeutet dies, dass ein kritischer Abschnitt verwendet wird. Angenommen, Thread T2 verwendet einen kritischen Abschnitt, dann werden die folgenden Schritte ausgeführt. T2:

  1. wait (s) // anfangs ist der Wert eins, nachdem wait aufgerufen wurde, und der Wert ist um eins verringert, d. h. 0
  2. Verwenden Sie einen kritischen Abschnitt
  3. signal (e) // Jetzt wird der Wert erhöht und zu 1

Der Hauptunterschied zwischen Mutex- und Binärsemaphor liegt in Mutext, wenn der kritische Abschnitt durch Thread-Sperre entsperrt wird und kein anderer Thread den kritischen Abschnitt entsperren kann. Bei Binärsemaphor wird der kritische Abschnitt durch die Funktion wait (s) gesperrt und der Wert angegeben von s wird "0" und niemand kann darauf zugreifen, bis der Wert von "s" 1 wird. Es wird jedoch angenommen, dass einige andere Thread-Aufrufsignale, dann wird der Wert von "s" 1, und andere Funktionen können den kritischen Abschnitt verwenden. daher hat in Binary Semaphore Thread kein Eigentum.

14
Sumit Naik

Sie verwenden offensichtlich Mutex, um Daten in einem Thread zu sperren, auf die gleichzeitig von einem anderen Thread zugegriffen wird. Angenommen, Sie haben gerade lock() aufgerufen und sind gerade dabei, auf Daten zuzugreifen. Dies bedeutet, dass Sie nicht erwarten, dass ein anderer Thread (oder eine andere Instanz desselben Thread-Codes) auf dieselben Daten zugreift, die von demselben Mutex gesperrt wurden. Wenn also derselbe Thread-Code, der auf einer anderen Thread-Instanz ausgeführt wird, auf die Sperre trifft, sollte lock() den dortigen Steuerfluss blockieren. Dies gilt für einen Thread, der einen anderen Thread-Code verwendet, der auf dieselben Daten zugreift und der auch durch denselben Mutex gesperrt ist. In diesem Fall greifen Sie noch auf die Daten zu, und Sie können beispielsweise weitere 15 Sekunden benötigen, um die Mutex-Freigabe zu erreichen (sodass der andere Thread, der in der Mutex-Sperre blockiert wird, die Sperre aufhebt und die Steuerung zulässt) auf die Daten zugreifen). Erlauben Sie auf jeden Fall einem weiteren Thread, denselben Mutex zu entsperren, und lassen Sie wiederum zu, dass der Thread, der bereits im Mutex-Schloss wartet (blockiert), die Blockierung aufhebt und auf die Daten zugreift? Hoffe du hast was ich hier sage? Gemäß vereinbarter universeller Definition!

  • mit "mutex" kann dies nicht passieren. Kein anderer Thread kann die Sperre in Ihrem Thread aufheben
  • mit "Binär-Semaphor" kann dies passieren. Jeder andere Thread kann die Sperre in Ihrem Thread aufheben

Wenn Sie also ganz besonders auf die Verwendung von Binärsemaphoren anstelle von Mutex Wert legen, sollten Sie beim „Scoping“ der Sperren und Entsperren sehr vorsichtig sein. Ich meine, dass jeder Kontrollfluss, der auf jede Sperre trifft, einen Aufruf zum Entsperren treffen sollte. Außerdem sollte es keine "erste Entsperrung" geben, sondern immer "erste Sperre".

10
paxi

Mutex werden für "Verriegelungsmechanismen" verwendet. Es kann jeweils ein Prozess eine gemeinsam genutzte Ressource verwenden

wohingegen

Semaphore werden für "Signalmechanismen" wie "Ich bin fertig, kann jetzt fortfahren" verwendet.

10
Jamshad Ahmad

Unter Windows gibt es zwei Unterschiede zwischen Mutexen und binären Semaphoren:

  1. Ein Mutex kann nur von dem Thread freigegeben werden, der den Besitz hat, d. H. Dem Thread, der zuvor die Wait-Funktion aufgerufen hat (oder der den Besitz beim Erstellen übernommen hat). Ein Semaphor kann von jedem Thread freigegeben werden.

  2. Ein Thread kann eine Wait-Funktion für einen Mutex wiederholt aufrufen, ohne ihn zu blockieren. Wenn Sie jedoch eine Wait-Funktion zweimal für ein binäres Semaphor aufrufen, ohne das Semaphor dazwischen freizugeben, wird der Thread blockiert.

10
Rich

Mythos:

In einigen Artikeln heißt es, dass "Binärsemaphor und Mutex gleich sind" oder "Semaphor mit Wert 1 ist Mutex", aber der grundlegende Unterschied ist, dass Mutex nur von dem Thread freigegeben werden kann, der es erworben hat, während Sie Semaphor von jedem anderen Thread signalisieren können

Wichtige Punkte:

• Ein Thread kann mehr als eine Sperre (Mutex) erhalten.

• Ein Mutex kann nur dann mehrmals gesperrt werden, wenn es sich um einen rekursiven Mutex handelt. Hier sollte das Sperren und Entsperren für Mutex identisch sein

• Wenn ein Thread, der bereits einen Mutex gesperrt hat, versucht, den Mutex erneut zu sperren, wird er in die Warteliste dieses Mutex aufgenommen, was zu einem Deadlock führt.

• Binärsemaphor und Mutex sind ähnlich, aber nicht gleich.

• Mutex ist aufgrund der damit verbundenen Schutzprotokolle ein kostspieliger Vorgang.

• Das Hauptziel von Mutex ist der atomare Zugriff oder die Sperre von Ressourcen

9
Saurabh Sinha

Ein Mutex steuert den Zugriff auf eine einzelne gemeinsam genutzte Ressource. Es bietet Operationen, um acquire () auf diese Ressource zuzugreifen und release (), wenn dies erledigt ist.

Ein Semaphor steuert den Zugriff auf einen gemeinsam genutzten Ressourcenpool. Es werden Operationen für Wait () bereitgestellt, bis eine der Ressourcen im Pool verfügbar ist, und Signal (), wenn sie an den Pool zurückgegeben werden.

Wenn die Anzahl der Ressourcen, die ein Semaphor schützt, größer als 1 ist, wird dies als Zählsemaphor bezeichnet. Wenn es eine Ressource steuert, heißt es Boolean Semaphore. Ein Boolesches Semaphor entspricht einem Mutex.

Somit ist ein Semaphor eine Abstraktion höherer Ebene als Mutex. Ein Mutex kann mit einem Semaphor implementiert werden, aber nicht umgekehrt.

8
Charan

Geänderte Frage ist - Was ist der Unterschied zwischen einem Mutex und einem "binären" Semaphor in "Linux"?

Antwort: Die folgenden Unterschiede sind zu beachten: i) Gültigkeitsbereich - Der Gültigkeitsbereich von mutex liegt in einem Prozessadressraum, in dem er erstellt wurde, und wird für die Synchronisierung von Threads verwendet. Während ein Semaphor prozessraumübergreifend verwendet werden kann, kann es für die Synchronisation zwischen Prozessen verwendet werden.

ii) Mutex ist leicht und schneller als Semaphor. Futex ist noch schneller.

iii) Mutex kann von demselben Thread mehrmals erfolgreich erworben werden, mit der Bedingung, dass er dieselbe Anzahl von Malen freigibt. Ein anderer Thread, der versucht zu erfassen, wird blockiert. Während im Falle eines Semaphors derselbe Prozess versucht, es erneut zu erfassen, wird es blockiert, da es nur einmal erfasst werden kann.

6
Mickey

Mutex-Arbeiten zur Blockierung der kritischen Region, aber Semaphore-Arbeiten zur Zählung.

6
Askkan

Unterschied zwischen binärem Semaphor und Mutex: EIGENTUM: Semaphore können auch von einem nicht aktuellen Besitzer signalisiert (gepostet) werden. Das bedeutet, dass Sie einfach von einem anderen Thread aus posten können, obwohl Sie nicht der Besitzer sind.

Semaphore ist eine in Bearbeitung befindliche öffentliche Eigenschaft. Sie kann einfach von einem Nicht-Eigentümer-Thread gepostet werden. Bitte kennzeichnen Sie diesen Unterschied in Fettdruck, er bedeutet sehr viel.

5
buddingspacer

http://www.geeksforgeeks.org/archives/9102 ausführlich besprochen.

Mutex ist ein Sperrmechanismus, mit dem der Zugriff auf eine Ressource synchronisiert wird. Semaphore ist ein Signalisierungsmechanismus.

Es liegt an dem Programmierer, ob er/sie ein binäres Semaphor anstelle eines Mutex verwenden möchte.

5
user1852497

In Windows ist der Unterschied wie folgt. MUTEX: Prozess, der erfolgreich ausgeführt wird Warten muss ein Signal ausführen und umgekehrt. BINARY SEMAPHORES: Verschiedene Prozesse können wait oder signal Operationen an einem Semaphor ausführen.

4
ajay bidari

Abgesehen von der Tatsache, dass Mutexe einen Eigentümer haben, können die beiden Objekte für eine unterschiedliche Verwendung optimiert werden. Mutexe sollen nur für kurze Zeit gehalten werden; Ein Verstoß dagegen kann zu einer schlechten Leistung und einer unfairen Zeitplanung führen. Beispielsweise kann es einem laufenden Thread gestattet sein, einen Mutex abzurufen, obwohl bereits ein anderer Thread darauf blockiert ist. Semaphoren können für mehr Fairness sorgen, oder Fairness kann mithilfe mehrerer Bedingungsvariablen erzwungen werden.

4
jilles

Das Konzept war mir klar, nachdem ich die obigen Beiträge durchgesehen hatte. Aber es gab noch einige Fragen. Also habe ich dieses kleine Stück Code geschrieben.

Wenn wir versuchen, ein Semaphor zu geben, ohne es zu nehmen, geht es durch. Wenn Sie jedoch versuchen, einen Mutex zu geben, ohne ihn zu übernehmen, schlägt dies fehl. Ich habe dies auf einer Windows-Plattform getestet. Aktivieren Sie USE_MUTEX, um denselben Code mit einem MUTEX auszuführen.

#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1

DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );

HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;


int main(void)
{

#ifdef USE_MUTEX
    ghMutex = CreateMutex( NULL, FALSE, NULL);
    if (ghMutex  == NULL) 
    {
        printf("CreateMutex error: %d\n", GetLastError());
        return 1;
    }
#else
    // Create a semaphore with initial and max counts of MAX_SEM_COUNT
    ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
    if (ghSemaphore == NULL) 
    {
        printf("CreateSemaphore error: %d\n", GetLastError());
        return 1;
    }
#endif
    // Create thread 1.
    Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);  
    if ( Handle_Of_Thread_1 == NULL)
    {
        printf("Create first thread problem \n");
        return 1;
    }

    /* sleep for 5 seconds **/
    Sleep(5 * 1000);

    /*Create thread 2 */
    Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);  
    if ( Handle_Of_Thread_2 == NULL)
    {
        printf("Create second thread problem \n");
        return 1;
    }

    // Sleep for 20 seconds
    Sleep(20 * 1000);

    printf("Out of the program \n");
    return 0;
}


int my_critical_section_code(HANDLE thread_handle)
{

#ifdef USE_MUTEX
    if(thread_handle == Handle_Of_Thread_1)
    {
        /* get the lock */
        WaitForSingleObject(ghMutex, INFINITE);
        printf("Thread 1 holding the mutex \n");
    }
#else
    /* get the semaphore */
    if(thread_handle == Handle_Of_Thread_1)
    {
        WaitForSingleObject(ghSemaphore, INFINITE);
        printf("Thread 1 holding semaphore \n");
    }
#endif

    if(thread_handle == Handle_Of_Thread_1)
    {
        /* sleep for 10 seconds */
        Sleep(10 * 1000);
#ifdef USE_MUTEX
        printf("Thread 1 about to release mutex \n");
#else
        printf("Thread 1 about to release semaphore \n");
#endif
    }
    else
    {
        /* sleep for 3 secconds */
        Sleep(3 * 1000);
    }

#ifdef USE_MUTEX
    /* release the lock*/
    if(!ReleaseMutex(ghMutex))
    {
        printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
    }
#else
    if (!ReleaseSemaphore(ghSemaphore,1,NULL) )      
    {
        printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
    }
#endif

    return 0;
}

DWORD WINAPI Thread_no_1( LPVOID lpParam ) 
{ 
    my_critical_section_code(Handle_Of_Thread_1);
    return 0;
}


DWORD WINAPI Thread_no_2( LPVOID lpParam ) 
{
    my_critical_section_code(Handle_Of_Thread_2);
    return 0;
}

Die bloße Tatsache, dass Sie mit einem Semaphor signalisieren können, dass "eine Ressource verwendet wird", obwohl die Ressource nie in ihrem Besitz war, lässt mich vermuten, dass es bei Semaphoren eine sehr lose Kopplung zwischen dem Besitzen und dem Signalisieren gibt.

4
Raghav Navada

Während ein binäres Semaphor als Mutex verwendet werden kann, ist ein Mutex ein spezifischerer Anwendungsfall, da nur der Prozess, der den Mutex gesperrt hat, ihn entsperren soll. Diese Eigentumsbeschränkung ermöglicht den Schutz vor:

  • Versehentliche Veröffentlichung
  • Rekursiver Deadlock
  • Aufgabe Death Deadlock

Diese Einschränkungen sind nicht immer vorhanden, da sie die Geschwindigkeit beeinträchtigen. Während der Entwicklung Ihres Codes können Sie diese Überprüfungen vorübergehend aktivieren.

z.B. Sie können das Fehlerprüfungsattribut in Ihrem Mutex aktivieren. Fehler beim Überprüfen von Mutexen geben EDEADLK zurück, wenn Sie versuchen, denselben zweimal zu sperren, und EPERM, wenn Sie einen Mutex entsperren, der nicht Ihnen gehört.

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

Nach der Initialisierung können wir diese Prüfungen wie folgt in unseren Code einfügen:

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");
3
Adi06411

Mutex wird zum Schutz des vertraulichen Codes und der Daten verwendet, Semaphor wird zur Synchronisierung verwendet. Sie können den vertraulichen Code auch praktisch schützen, es besteht jedoch die Gefahr, dass der Schutz durch den anderen Thread durch die Operation V.So aufgehoben wird Unterschied zwischen Bisemaphor und Mutex ist das Eigentum. Zum Beispiel durch Toilette, Mutex ist so, dass man die Toilette betreten und die Tür abschließen kann, niemand sonst kann eintreten, bis der Mann aussteigt, Bisemaphor ist so, dass man eintreten kann die Toilette und die Tür abschließen, aber jemand anderes kann eintreten, indem er den Administrator bittet, die Tür zu öffnen, es ist lächerlich.

2
mannnnerd

Mutex

Mutexe werden normalerweise verwendet, um den Zugriff auf einen Teil des wiedereintretenden Codes zu serialisieren, der nicht von mehr als einem Thread gleichzeitig ausgeführt werden kann. Ein Mutex-Objekt lässt nur einen Thread in einen kontrollierten Abschnitt zu und zwingt andere Threads, die versuchen, auf diesen Abschnitt zuzugreifen, zu warten, bis der erste Thread diesen Abschnitt verlassen hat. Die ordnungsgemäße Verwendung eines Mutex zum Schutz einer gemeinsam genutzten Ressource kann gefährlich sein unbeabsichtigte Nebenwirkung. Beliebige zwei RTOS Tasks, die mit unterschiedlichen Prioritäten arbeiten und über einen Mutex koordinieren, schaffen die Möglichkeit für Prioritätsumkehrung. Mutex funktioniert in User Space.

Semaphor

Semaphor ist ein Signalmechanismus. Semaphore schränkt die Anzahl gleichzeitiger Benutzer einer freigegebenen Ressource auf eine maximale Anzahl ein. Threads können den Zugriff auf die Ressource anfordern (Dekrementieren des Semaphors) und signalisieren, dass sie die Ressource nicht mehr verwenden (Inkrementieren des Semaphors). Es ermöglicht die Anzahl der Threads, auf gemeinsam genutzte Ressourcen zuzugreifen. Die korrekte Verwendung eines Semaphors dient zum Signalisieren von einer Task zu einer anderen. Semaphoren können auch zum Signalisieren von einer Interrupt-Serviceroutine verwendet werden (ISR) zu einer Aufgabe. Das Signalisieren eines Semaphors ist ein nicht blockierendes RTOS und damit ISR-sicher. Durch diese Technik entfällt das fehleranfällige Deaktivieren von Interrupts auf Task-Ebene. Dies funktioniert in kernel space.

1
Gopika BG

Mutexe haben im Gegensatz zu Semaphoren Eigentum. Obwohl jeder Thread im Rahmen eines Mutex einen nicht gesperrten Mutex erhalten und den Zugriff auf denselben kritischen Codeabschnitt sperren kann , nur der Thread, der einen Mutex gesperrt hat sollte = entsperren .

1
laksbv

Die Antwort kann vom Zielbetriebssystem abhängen. Zum Beispiel erlaubt mindestens eine mir vertraute RTOS Implementierung mehrere sequentielle "get" -Operationen für einen einzelnen OS-Mutex, solange sie alle aus demselben Thread-Kontext stammen. Die mehreren Abrufe müssen durch die gleiche Anzahl von Puts ersetzt werden, bevor ein anderer Thread den Mutex abrufen kann. Dies unterscheidet sich von binären Semaphoren, für die unabhängig vom Thread-Kontext immer nur ein Abruf zulässig ist.

Die Idee hinter dieser Art von Mutex ist, dass Sie ein Objekt schützen, indem Sie jeweils nur einem Kontext erlauben, die Daten zu ändern. Auch wenn der Thread den Mutex abruft und dann eine Funktion aufruft, die das Objekt weiter modifiziert (und den Protector-Mutex um seine eigenen Operationen herum abruft/platziert), sollten die Operationen dennoch sicher sein, da sie alle unter einem einzigen Thread ablaufen.

{
    mutexGet();  // Other threads can no longer get the mutex.

    // Make changes to the protected object.
    // ...

    objectModify();  // Also gets/puts the mutex.  Only allowed from this thread context.

    // Make more changes to the protected object.
    // ...

    mutexPut();  // Finally allows other threads to get the mutex.
}

Wenn Sie diese Funktion verwenden, müssen Sie natürlich sicher sein, dass alle Zugriffe in einem einzelnen Thread wirklich sicher sind!

Ich bin nicht sicher, wie weit verbreitet dieser Ansatz ist oder ob er außerhalb der mir vertrauten Systeme angewendet wird. Ein Beispiel für diese Art von Mutex finden Sie im ThreadX-RTOS.

1
Casey Barker

Wie viele Leute hier erwähnt haben, wird ein Mutex verwendet, um einen kritischen Teil des Codes zu schützen (kritischer Abschnitt der AKA). Sie werden den Mutex erwerben (sperren), den kritischen Abschnitt betreten und den Mutex freigeben (entsperren) alles in der gleicher Thread.

Während Sie ein Semaphor verwenden, können Sie einen Thread auf ein Semaphor warten lassen (z. B. Thread A), bis ein anderer Thread (z. B. Thread B) die Aufgabe abgeschlossen hat, und dann das Semaphor für Thread A festlegen, um das Warten zu beenden und die Aufgabe fortzusetzen.

1
Dom045

Das Grundproblem ist die Parallelität. Es gibt mehr als einen Kontrollfluss. Stellen Sie sich zwei Prozesse mit einem gemeinsam genutzten Speicher vor. Jetzt kann immer nur ein Prozess auf den gemeinsamen Speicher zugreifen. Wenn mehr als ein Prozess gleichzeitig auf den gemeinsam genutzten Speicher zugreift, wird der Inhalt des gemeinsam genutzten Speichers beschädigt. Es ist wie eine Eisenbahnstrecke. Es kann nur ein Zug darauf fahren, sonst würde es zu einem Unfall kommen. Es gibt also einen Signalmechanismus, den ein Fahrer überprüft. Wenn das Signal grün ist, kann der Zug fahren und wenn es rot ist, muss er warten, um die Strecke zu benutzen. In ähnlicher Weise gibt es im Fall eines gemeinsam genutzten Speichers ein binäres Semaphor. Wenn das Semaphor 1 ist, erfasst ein Prozess es (macht es zu 0) und geht weiter und greift darauf zu. Wenn das Semaphor 0 ist, wartet der Prozess. Die Funktionalität, die das binäre Semaphor bieten muss, ist gegenseitiger Ausschluss (oder kurz Mutex), sodass nur eine der vielen gleichzeitigen Entitäten (Prozess oder Thread) andere gegenseitig ausschließt. Es ist ein Plus, dass wir Semaphoren zählen, die bei der Synchronisierung mehrerer Instanzen einer Ressource helfen.

Gegenseitiger Ausschluss ist die Grundfunktionalität von Semaphoren. Im Zusammenhang mit Threads haben wir möglicherweise einen anderen Namen und eine andere Syntax dafür. Das zugrunde liegende Konzept ist jedoch dasselbe: Wie kann die Integrität von Code und Daten bei der gleichzeitigen Programmierung gewährleistet werden? Meiner Meinung nach sind Dinge wie Eigentum und damit verbundene Prüfungen Verfeinerungen, die von Implementierungen bereitgestellt werden.

0
kjohri

Mutex und binäres Semaphor werden beide gleich verwendet, aber in Wirklichkeit sind sie unterschiedlich.

Im Fall von Mutex kann nur der Thread, der es gesperrt hat, es entsperren. Wenn ein anderer Thread zum Sperren kommt, wartet er.

Beim Semaphon ist das nicht der Fall. Semaphore ist nicht mit einer bestimmten Thread-ID verknüpft.

0
Neeraj Sh

"binäres Semaphor" ist eine Programmiersprache, die es umgeht, ein "Semaphor" wie "Mutex" zu verwenden. Anscheinend gibt es zwei sehr große Unterschiede:

  1. Die Art, wie Sie jeden von ihnen anrufen.

  2. Die maximale Länge des "Bezeichners".

0
ilias iliadis