Lock, Mutex, Semaphor ... was ist der Unterschied?

Antworten:

533

Durch eine Sperre kann nur ein Thread in das gesperrte Teil eintreten, und die Sperre wird nicht für andere Prozesse freigegeben.

Ein Mutex ist dasselbe wie eine Sperre, kann jedoch systemweit sein (von mehreren Prozessen gemeinsam genutzt).

Ein Semaphor macht dasselbe wie ein Mutex, erlaubt jedoch die Eingabe von x Threads. Dies kann beispielsweise verwendet werden, um die Anzahl der gleichzeitig ausgeführten CPU-, Io- oder RAM-intensiven Tasks zu begrenzen.

Einen ausführlicheren Beitrag über die Unterschiede zwischen Mutex und Semaphor finden Sie hier .

Sie haben auch Lese- / Schreibsperren, die entweder eine unbegrenzte Anzahl von Lesern oder 1 Schreiber gleichzeitig zulassen.

Peter
quelle
2
@mertinan Ich kann nicht sagen, dass ich jemals davon gehört habe, aber dies ist, was Wikipedia sagt "Latch (Datenbank), eine (relativ kurzlebige) Sperre für eine Systemdatenstruktur wie einen Index"
Peter
2
Monitor ermöglicht das Warten auf einen bestimmten Zustand (z. B. wenn die Sperre aufgehoben ist), "überwacht".
Dzmitry Lazerka
25
Ein Semaphor ist nicht dasselbe wie ein Mutex. Sie werden sehr unterschiedlich verwendet und haben auch unterschiedliche Eigenschaften (nämlich in Bezug auf das Eigentum). Siehe zum Beispiel barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore für Details
Nanoquack
3
@nanoquack Sie können meine Antwort jederzeit bearbeiten, wenn Sie der Meinung sind, dass sie irreführend oder falsch ist.
Peter
3
Für eine klarere Unterscheidung zwischen Mutex und Semaphor in Nanoquacks Link lautet der Hauptabsatz " Die korrekte Verwendung eines Semaphors dient der Signalisierung von einer Aufgabe zur anderen. Ein Mutex soll von jedem immer in dieser Reihenfolge genommen und freigegeben werden Aufgabe, die die gemeinsam genutzte Ressource verwendet, die sie schützt. Im Gegensatz dazu signalisieren Aufgaben, die Semaphoren verwenden, entweder oder warten - nicht beide. "
ToolmakerSteve
117

Es gibt viele Missverständnisse in Bezug auf diese Wörter.

Dies ist aus einem früheren Beitrag ( https://stackoverflow.com/a/24582076/3163691 ), der hier hervorragend passt:

1) Kritischer Abschnitt = Benutzerobjekt, mit dem nur ein aktiver Thread von vielen anderen innerhalb eines Prozesses ausgeführt werden kann . Die anderen nicht ausgewählten Threads (@, die dieses Objekt erfassen) werden in den Ruhezustand versetzt .

[Keine Interprozessfähigkeit, sehr primitives Objekt].

2) Mutex-Semaphor (auch bekannt als Mutex) = Kernel-Objekt, mit dem nur ein aktiver Thread von vielen anderen unter verschiedenen Prozessen ausgeführt werden kann . Die anderen nicht ausgewählten Threads (@, die dieses Objekt erfassen) werden in den Ruhezustand versetzt . Dieses Objekt unterstützt Thread-Besitz, Benachrichtigung über die Beendigung des Threads, Rekursion (mehrere Aufrufe von demselben Thread abrufen) und Vermeidung von Prioritätsumkehrungen.

[Interprozessfähigkeit, sehr sicher zu bedienen, eine Art Synchronisationsobjekt auf hoher Ebene].

3) Counting Semaphore (auch bekannt als Semaphore) = Kernel-Objekt, mit dem eine Gruppe aktiver Threads von vielen anderen ausgeführt werden kann. Die anderen nicht ausgewählten Threads (@, die dieses Objekt erfassen) werden in den Ruhezustand versetzt .

[Die Interprozessfähigkeit ist jedoch nicht sehr sicher zu verwenden, da die folgenden 'Mutex'-Attribute fehlen: Benachrichtigung über Thread-Beendigung, Rekursion?,' Vermeidung von Prioritätsumkehrungen 'usw.].

4) Und jetzt, wenn wir über 'Spinlocks' sprechen, zuerst einige Definitionen:

Kritischer Bereich = Ein Speicherbereich, der von zwei oder mehr Prozessen gemeinsam genutzt wird.

Lock = Eine Variable, deren Wert den Zugang zu einem 'kritischen Bereich' erlaubt oder verweigert. (Es könnte als einfaches 'Boolesches Flag' implementiert werden).

Besetztes Warten = Kontinuierliches Testen einer Variablen, bis ein Wert angezeigt wird.

Schließlich:

Spin-Lock (auch bekannt als Spinlock) = Eine Sperre, bei der viel gewartet wird . (Der Erwerb der Sperre erfolgt durch xchg oder ähnliche atomare Operationen ).

[Kein Thread schlafen, meistens nur auf Kernel-Ebene verwendet. Ineffizient für Code auf Benutzerebene].

Als letzten Kommentar bin ich mir nicht sicher, aber ich kann wetten, dass die oben genannten ersten 3 Synchronisierungsobjekte (Nr. 1, Nr. 2 und Nr. 3) dieses einfache Biest (Nr. 4) als Teil ihrer Implementierung verwenden.

Haben Sie einen guten Tag!.

Verweise:

-Real-Time-Konzepte für eingebettete Systeme von Qing Li mit Caroline Yao (CMP Books).

-Moderne Betriebssysteme (3.) von Andrew Tanenbaum (Pearson Education International).

-Programmieranwendungen für Microsoft Windows (4.) von Jeffrey Richter (Microsoft Programming Series).

Sie können auch einen Blick darauf werfen: https://stackoverflow.com/a/24586803/3163691

fante
quelle
1
Tatsächlich ist ein kritischer Abschnitt kein Kernelobjekt, daher leichter und nicht in der Lage, prozessübergreifend zu synchronisieren.
Vladislavs Burakovs
2
@ Vladislavs Burakovs: Du hast recht! Vergib mir meine Redaktion. Ich werde es aus Gründen der Kohärenz beheben.
Fante
Für eine klarere Unterscheidung zwischen Mutex und Semaphor, wie Nanoquack an anderer Stelle erwähnt, siehe barrgroup.com/Embedded-Systems/How-To/RTOS-Mutex-Semaphore - Der Hauptabsatz lautet " Die korrekte Verwendung eines Semaphors dient der Signalisierung von einer Aufgabe." Ein Mutex soll von jeder Aufgabe, die die gemeinsam genutzte Ressource verwendet, die sie schützt, immer in dieser Reihenfolge verwendet und freigegeben werden. Im Gegensatz dazu signalisieren oder warten Aufgaben, die Semaphoren verwenden, entweder oder nicht
ToolmakerSteve
Vermutung, dass andere Verriegelungsmechanismen auf [ineffizientem] Spinlock aufbauen: unwahrscheinlich; AFAIK benötigt nur einige atomare Operationen plus Schlafwarteschlangen. Selbst dort , wo spinlock wird innerhalb Kernel benötigt, minimieren moderne Lösungen ihre Auswirkungen wie in die Wikipedia - Spinlock - Alternativen - " adaptives Mutex‚.. einen hybriden Ansatz namens verwenden‘Die Idee ist es, einen Spinlock zu verwenden , wenn eine Ressource gesperrt zuzugreifen versuchen , durch. Ein aktuell laufender Thread, der jedoch in den Ruhezustand versetzt wird, wenn der Thread derzeit nicht ausgeführt wird. (Letzteres ist auf Einzelprozessorsystemen immer der Fall.) "
ToolmakerSteve
@ToolmakerSteve, ich wage Sie, eine "Lösung" ohne "Spinlock" für das Problem der "Kollisionen" beim Versuch, eine Thread-ID in eine "Schlafwarteschlange" einzufügen, bereitzustellen. Wie auch immer, der Wikipedia-Text kommt zu dem Schluss, dass bei der Implementierung ein Spinlock verwendet wird !!!.
Fante
27

Die meisten Probleme können mit (i) nur Sperren, (ii) nur Semaphoren, ... oder (iii) einer Kombination aus beiden gelöst werden! Wie Sie vielleicht festgestellt haben, sind sie sich sehr ähnlich: Beide verhindern Rennbedingungen , beide haben acquire()/ release()Operationen, beide führen dazu, dass null oder mehr Threads blockiert / vermutet werden ... Der entscheidende Unterschied liegt wirklich nur darin, wie sie sperren und entsperren .

  • Eine Sperre (oder ein Mutex ) hat zwei Zustände (0 oder 1). Es kann entweder entsperrt oder gesperrt werden . Sie werden häufig verwendet, um sicherzustellen, dass jeweils nur ein Thread in einen kritischen Abschnitt eintritt.
  • Ein Semaphor hat viele Zustände (0, 1, 2, ...). Es kann gesperrt (Status 0) oder entsperrt (Status 1, 2, 3, ...) sein. Ein oder mehrere Semaphore werden häufig zusammen verwendet, um sicherzustellen, dass nur ein Thread genau dann in einen kritischen Abschnitt eintritt, wenn die Anzahl der Einheiten einer Ressource einen bestimmten Wert erreicht hat / nicht erreicht hat (entweder durch Herunterzählen bis zu diesem Wert oder durch Hochzählen bis zu diesem Wert ).

Bei beiden Sperren / Semaphoren wird beim Versuch, einen Aufruf durchzuführen, acquire()während sich das Grundelement im Status 0 befindet, der aufrufende Thread angehalten. Für Sperren - Versuche, die Sperre im Status 1 zu erhalten, sind erfolgreich. Für Semaphore - Versuche, die Sperre in den Zuständen {1, 2, 3, ...} zu erlangen, sind erfolgreich.

Wenn für Sperren im Status 0 derselbe Thread, der zuvor aufgerufen wurde acquire(), jetzt die Freigabe aufruft, ist die Freigabe erfolgreich. Wenn ein anderer Thread dies versucht hat, liegt es an der Implementierung / Bibliothek, was passiert (normalerweise wird der Versuch ignoriert oder ein Fehler wird ausgelöst). Bei Semaphoren im Status 0 kann jeder Thread die Freigabe aufrufen und ist erfolgreich (unabhängig davon, welcher Thread zuvor verwendet wurde, um das Semaphor in den Status 0 zu versetzen).

Aus der vorangegangenen Diskussion können wir ersehen, dass Sperren den Begriff eines Besitzers haben (der einzige Thread, der die Freigabe aufrufen kann, ist der Eigentümer), während Semaphoren keinen Eigentümer haben (jeder Thread kann die Freigabe eines Semaphors aufrufen).


Was viel Verwirrung stiftet, ist, dass es sich in der Praxis um viele Variationen dieser Definition auf hoher Ebene handelt.

Wichtige zu berücksichtigende Variationen :

  • Was sollte der acquire()/ release()genannt werden? - [Variiert massiv ]
  • Verwendet Ihre Sperre / Ihr Semaphor eine "Warteschlange" oder ein "Set", um sich an die wartenden Threads zu erinnern?
  • Kann Ihre Sperre / Ihr Semaphor mit Threads anderer Prozesse geteilt werden?
  • Ist Ihr Schloss "wiedereintrittsfähig"? - [Normalerweise ja].
  • Ist Ihr Schloss "blockierend / nicht blockierend"? - [Normalerweise werden nicht blockierende Sperren verwendet, da blockierende Sperren (auch als Spin-Sperren bezeichnet) zu beschäftigtem Warten führen].
  • Wie stellen Sie sicher, dass die Operationen "atomar" sind?

Dies hängt von Ihrem Buch / Dozenten / Sprache / Bibliothek / Umgebung ab.
Hier ist eine kurze Tour, in der erläutert wird, wie einige Sprachen diese Details beantworten.


C, C ++ ( Pthreads )

  • Ein Mutex wird über implementiert pthread_mutex_t. Standardmäßig können sie nicht mit anderen Prozessen ( PTHREAD_PROCESS_PRIVATE) geteilt werden, Mutex haben jedoch ein Attribut namens pshared . Wenn festgelegt, wird der Mutex von Prozessen geteilt ( PTHREAD_PROCESS_SHARED).
  • Ein Schloss ist dasselbe wie ein Mutex.
  • Ein Semaphor wird über implementiert sem_t. Ähnlich wie bei Mutexen können Semaphoren von mehreren Prozessen gemeinsam genutzt oder für die Threads eines einzelnen Prozesses privat gehalten werden. Dies hängt vom angegebenen Argument pshared absem_init .

Python ( threading.py )

  • Ein lock ( threading.RLock) ist meistens dasselbe wie C / C ++ pthread_mutex_ts. Beide sind wiedereintrittsfähig . Dies bedeutet, dass sie möglicherweise nur von demselben Thread entsperrt werden, der sie gesperrt hat. Es ist der Fall, dass sem_tSemaphoren, threading.SemaphoreSemaphoren und theading.LockSperren nicht wiedereintrittsfähig sind - denn es ist der Fall, dass jeder Thread das Sperren / Sperren des Semaphors durchführen kann.
  • Ein Mutex ist dasselbe wie eine Sperre (der Begriff wird in Python nicht oft verwendet).
  • Ein Semaphor ( threading.Semaphore) ist meistens dasselbe wie sem_t. Obwohl mit sem_t, wird eine Warteschlange mit Thread-IDs verwendet, um die Reihenfolge zu speichern, in der Threads blockiert wurden, als versucht wurde, sie zu sperren, während sie gesperrt sind. Wenn ein Thread ein Semaphor entsperrt, wird der erste Thread in der Warteschlange (falls vorhanden) als neuer Eigentümer ausgewählt. Die Thread-ID wird aus der Warteschlange entfernt und das Semaphor wird wieder gesperrt. Bei wird jedoch threading.Semaphoreein Satz anstelle einer Warteschlange verwendet, sodass die Reihenfolge, in der Threads blockiert wurden, nicht gespeichert wird. Jeder Thread im Satz kann als nächster Eigentümer ausgewählt werden.

Java ( java.util.concurrent )

  • Ein lock ( java.util.concurrent.ReentrantLock) ist größtenteils dasselbe wie das von C / C ++ pthread_mutex_tund das von Python, threading.RLockda es auch eine wiedereintrittssperre implementiert. Das Teilen von Sperren zwischen Prozessen ist in Java schwieriger, da die JVM als Vermittler fungiert. Wenn ein Thread versucht, eine Sperre zu entsperren, die er nicht besitzt, wird eine IllegalMonitorStateExceptionausgelöst.
  • Ein Mutex ist dasselbe wie eine Sperre (der Begriff wird in Java nicht oft verwendet).
  • Ein Semaphor ( java.util.concurrent.Semaphore) ist meistens dasselbe wie sem_tund threading.Semaphore. Der Konstruktor für Java-Semaphoren akzeptiert einen booleschen Fairness- Parameter, der steuert, ob ein Satz (false) oder eine Warteschlange (true) zum Speichern der wartenden Threads verwendet werden soll.

In der Theorie werden Semaphoren oft diskutiert, in der Praxis werden Semaphoren jedoch nicht so häufig verwendet. Ein Semaphor enthält nur den Status einer Ganzzahl, daher ist es oft ziemlich unflexibel und viele werden gleichzeitig benötigt - was zu Schwierigkeiten beim Verständnis von Code führt. Auch die Tatsache, dass jeder Thread ein Semaphor freigeben kann, ist manchmal unerwünscht. Stattdessen werden objektorientiertere / übergeordnete Synchronisationsprimitive / -abstraktionen wie "Bedingungsvariablen" und "Monitore" verwendet.

James Lawson
quelle
22

Schauen Sie sich das Multithreading-Tutorial von John Kopplin an.

Im Abschnitt Synchronisation zwischen Threads erklärt er die Unterschiede zwischen Ereignis, Sperre, Mutex, Semaphor und wartbarem Timer

Ein Mutex kann jeweils nur einem Thread gehören, sodass Threads den sich gegenseitig ausschließenden Zugriff auf eine gemeinsam genutzte Ressource koordinieren können

Kritische Abschnittsobjekte mit bieten eine ähnliche Synchronisation wie Mutex-Objekte, mit der Ausnahme, dass Objekte mit kritischen Abschnitten nur von den Threads eines einzelnen Prozesses verwendet werden können

Ein weiterer Unterschied zwischen einem Mutex und einem kritischen Abschnitt besteht darin, dass, wenn das Objekt des kritischen Abschnitts derzeit einem anderen Thread gehört, EnterCriticalSection()auf unbestimmte Zeit auf den Besitz gewartet wird WaitForSingleObject() , bei Verwendung eines Mutex ein Zeitlimit angegeben werden kann

Ein Semaphor behält eine Zählung zwischen Null und einem Maximalwert bei, wodurch die Anzahl der Threads begrenzt wird, die gleichzeitig auf eine gemeinsam genutzte Ressource zugreifen.

onmyway133
quelle
15

Ich werde versuchen, es mit Beispielen zu behandeln:

Sperren: Ein Beispiel, das Sie verwenden würden, lockwäre ein freigegebenes Wörterbuch, in das Elemente (die eindeutige Schlüssel haben müssen) hinzugefügt werden.
Die Sperre würde sicherstellen, dass ein Thread nicht den Code-Mechanismus eingibt, der prüft, ob sich ein Element im Wörterbuch befindet, während ein anderer Thread (der sich im kritischen Abschnitt befindet) diese Prüfung bereits bestanden hat und das Element hinzufügt. Wenn ein anderer Thread versucht, einen gesperrten Code einzugeben, wartet er (wird blockiert), bis das Objekt freigegeben wird.

private static readonly Object obj = new Object();

lock (obj) //after object is locked no thread can come in and insert item into dictionary on a different thread right before other thread passed the check...
{
    if (!sharedDict.ContainsKey(key))
    {
        sharedDict.Add(item);
    }
}

Semaphor: Angenommen, Sie haben einen Pool von Verbindungen. Dann kann ein einzelner Thread ein Element im Pool reservieren, indem er darauf wartet, dass das Semaphor eine Verbindung erhält. Anschließend wird die Verbindung verwendet, und wenn die Arbeit erledigt ist, wird die Verbindung durch Freigeben des Semaphors freigegeben.

Das Codebeispiel, das ich liebe, ist eines der Türsteher von @Patric - hier ist es:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TheNightclub
{
    public class Program
    {
        public static Semaphore Bouncer { get; set; }

        public static void Main(string[] args)
        {
            // Create the semaphore with 3 slots, where 3 are available.
            Bouncer = new Semaphore(3, 3);

            // Open the nightclub.
            OpenNightclub();
        }

        public static void OpenNightclub()
        {
            for (int i = 1; i <= 50; i++)
            {
                // Let each guest enter on an own thread.
                Thread thread = new Thread(new ParameterizedThreadStart(Guest));
                thread.Start(i);
            }
        }

        public static void Guest(object args)
        {
            // Wait to enter the nightclub (a semaphore to be released).
            Console.WriteLine("Guest {0} is waiting to entering nightclub.", args);
            Bouncer.WaitOne();          

            // Do some dancing.
            Console.WriteLine("Guest {0} is doing some dancing.", args);
            Thread.Sleep(500);

            // Let one guest out (release one semaphore).
            Console.WriteLine("Guest {0} is leaving the nightclub.", args);
            Bouncer.Release(1);
        }
    }
}

Mutex Es wird ziemlich Semaphore(1,1)häufig und häufig weltweit verwendet (anwendungsweit, ansonsten wohl lockbesser geeignet). Man würde global verwenden, Mutexwenn ein Knoten aus einer global zugänglichen Liste gelöscht wird (als letztes soll ein anderer Thread etwas tun, während Sie den Knoten löschen). Wenn Sie feststellen, Mutexob ein anderer Thread versucht, dasselbe Mutexzu erfassen, wird er in den Ruhezustand versetzt, bis derselbe Thread, der den Erwerb erhalten hat, ihn Mutexfreigibt.

Ein gutes Beispiel für die Erstellung eines globalen Mutex ist @deepee

class SingleGlobalInstance : IDisposable
{
    public bool hasHandle = false;
    Mutex mutex;

    private void InitMutex()
    {
        string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
        string mutexId = string.Format("Global\\{{{0}}}", appGuid);
        mutex = new Mutex(false, mutexId);

        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);
    }

    public SingleGlobalInstance(int timeOut)
    {
        InitMutex();
        try
        {
            if(timeOut < 0)
                hasHandle = mutex.WaitOne(Timeout.Infinite, false);
            else
                hasHandle = mutex.WaitOne(timeOut, false);

            if (hasHandle == false)
                throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
        }
        catch (AbandonedMutexException)
        {
            hasHandle = true;
        }
    }


    public void Dispose()
    {
        if (mutex != null)
        {
            if (hasHandle)
                mutex.ReleaseMutex();
            mutex.Dispose();
        }
    }
}

dann benutze wie:

using (new SingleGlobalInstance(1000)) //1000ms timeout on global lock
{
    //Only 1 of these runs at a time
    GlobalNodeList.Remove(node)
}

Hoffe das spart dir etwas Zeit.

Matas Vaitkevicius
quelle
8

Wikipedia hat einen großartigen Abschnitt über die Unterschiede zwischen Semaphoren und Mutexen :

Ein Mutex ist im Wesentlichen dasselbe wie ein binäres Semaphor und verwendet manchmal dieselbe grundlegende Implementierung. Die Unterschiede zwischen ihnen sind:

Mutexe haben das Konzept eines Besitzers. Dies ist der Prozess, der den Mutex gesperrt hat. Nur der Prozess, der den Mutex gesperrt hat, kann ihn entsperren. Im Gegensatz dazu hat ein Semaphor kein Konzept eines Besitzers. Jeder Prozess kann ein Semaphor entsperren.

Im Gegensatz zu Semaphoren bieten Mutexe vorrangige Inversionssicherheit. Da der Mutex seinen aktuellen Besitzer kennt, ist es möglich, die Priorität des Besitzers zu erhöhen, wenn eine Aufgabe mit höherer Priorität auf den Mutex wartet.

Mutexe bieten auch Löschsicherheit, wenn der Prozess, der den Mutex enthält, nicht versehentlich gelöscht werden kann. Semaphoren bieten dies nicht.

Andy Boot
quelle
5

Nach meinem Verständnis kann ein Mutex nur innerhalb eines einzelnen Prozesses verwendet werden, jedoch über mehrere Threads hinweg, während ein Semaphor über mehrere Prozesse hinweg und über die entsprechenden Thread-Sätze hinweg verwendet werden kann.

Außerdem ist ein Mutex binär (entweder gesperrt oder entsperrt), während ein Semaphor den Begriff des Zählens oder eine Warteschlange mit mehr als einer Anforderung zum Sperren und Entsperren hat.

Könnte jemand meine Erklärung überprüfen? Ich spreche im Zusammenhang mit Linux, insbesondere Red Hat Enterprise Linux (RHEL) Version 6, die Kernel 2.6.32 verwendet.

Bruce Penswick
quelle
3
Nun mag dies in verschiedenen Betriebssystemen unterschiedlich sein, aber in Windows kann ein Mutex von mehreren Prozessen verwendet werden, zumindest das .net Mutex-Objekt.
Peter
2
stackoverflow.com/questions/9389730/… "Threads innerhalb desselben Prozesses oder innerhalb anderer Prozesse können Mutexe gemeinsam nutzen." Ein Mutex darf also nicht prozessspezifisch sein.
Peter
3

Verwenden der C-Programmierung unter einer Linux-Variante als Basis für Beispiele.

Sperren:

• Normalerweise ist eine sehr einfache Konstrukt-Binärdatei im Betrieb entweder gesperrt oder entsperrt

• Kein Konzept für Thread-Besitz, Priorität, Sequenzierung usw.

• Normalerweise eine Drehsperre, bei der der Thread kontinuierlich die Verfügbarkeit der Sperren überprüft.

• Verlässt sich normalerweise auf atomare Operationen, z. B. Testen und Setzen, Vergleichen und Tauschen, Abrufen und Hinzufügen usw.

• Erfordert normalerweise Hardware-Unterstützung für den atomaren Betrieb.

Dateisperren:

• Wird normalerweise verwendet, um den Zugriff auf eine Datei über mehrere Prozesse zu koordinieren.

• Mehrere Prozesse können die Lesesperre halten. Wenn jedoch ein einzelner Prozess die Schreibsperre hält, darf kein anderer Prozess eine Lese- oder Schreibsperre erwerben.

• Beispiel: Herde, fcntl etc ..

Mutex:

• Mutex-Funktionsaufrufe funktionieren normalerweise im Kernelraum und führen zu Systemaufrufen.

• Es verwendet das Konzept des Eigentums. Nur der Thread, der derzeit den Mutex enthält, kann ihn entsperren.

• Mutex ist nicht rekursiv (Ausnahme: PTHREAD_MUTEX_RECURSIVE).

• Wird normalerweise in Verbindung mit Bedingungsvariablen verwendet und als Argumente an z. B. pthread_cond_signal, pthread_cond_wait usw. übergeben.

• Einige UNIX-Systeme ermöglichen die Verwendung von Mutex durch mehrere Prozesse, obwohl dies möglicherweise nicht auf allen Systemen erzwungen wird.

Semaphor:

• Dies ist eine vom Kernel gepflegte Ganzzahl, deren Werte nicht unter Null fallen dürfen.

• Es kann verwendet werden, um Prozesse zu synchronisieren.

• Der Wert des Semaphors kann auf einen Wert größer als 1 festgelegt werden. In diesem Fall gibt der Wert normalerweise die Anzahl der verfügbaren Ressourcen an.

• Ein Semaphor, dessen Wert auf 1 und 0 beschränkt ist, wird als binäres Semaphor bezeichnet.

Judayle Dsouza
quelle
0

Supporting ownership, maximum number of processes share lock und das maximum number of allowed processes/threads in critical sectionsind drei Hauptfaktoren, die den Namen / Typ des gleichzeitigen Objekts mit dem allgemeinen Namen von bestimmen lock. Da der Wert dieser Faktoren binär ist (zwei Zustände hat), können wir sie in einer 3 * 8-Wahrheitstabelle zusammenfassen.

  • X (Unterstützt die Eigentümerschaft?): Nein (0) / Ja (1)
  • Y (# Sharing-Prozesse):> 1 (∞) / 1
  • Z (# Prozesse / Threads in CA):> 1 (∞) / 1

  X   Y   Z          Name
 --- --- --- ------------------------
  0   ∞   ∞   Semaphore              
  0   ∞   1   Binary Semaphore       
  0   1   ∞   SemaphoreSlim          
  0   1   1   Binary SemaphoreSlim(?)
  1   ∞   ∞   Recursive-Mutex(?)     
  1   ∞   1   Mutex                  
  1   1   ∞   N/A(?)                 
  1   1   1   Lock/Monitor           

Fühlen Sie sich frei, diese Tabelle zu bearbeiten oder zu erweitern. Ich habe sie als ASCII-Tabelle veröffentlicht, damit sie bearbeitet werden kann :)

Faghani
quelle