nette, go-idiomatische Art der Verwendung einer geteilten Map

7

Angenommen, ich hätte ein Programm mit gleichzeitigem Zugriff auf eine Karte, wie folgt:

%Vor%

Dies ist schlecht, da Kartenschreibvorgänge nicht atomar sind. Also konnte ich einen Lese- / Schreib-Mutex verwenden

%Vor%

Das scheint in Ordnung, abgesehen von der Tatsache, dass wir direkt Mutexe und keine Kanäle verwenden.

Was ist eine mehr als idiomatische Art, dies zu implementieren? Oder ist das eine jener Zeiten, in denen ein Mutex wirklich alles ist, was du brauchst?

    
Alec 12.08.2013, 16:34
quelle

4 Antworten

8

Ich denke, diese Größenordnung hängt von Ihren Leistungserwartungen ab und davon, wie diese Karte letztendlich verwendet wird.

Als ich diese Frage recherchierte, stieß ich auf diesen sehr hilfreichen Artikel, der deine Frage beantworten sollte a>.

Meine persönliche Antwort ist, dass Sie Kanäle standardmäßig verwenden sollten, es sei denn, Sie finden wirklich die Notwendigkeit, einen Mutex zu verwenden. Der zentrale Punkt von idiomatic Go besteht darin, dass Sie keine Mutexe verwenden müssen und sich nicht um Sperren kümmern müssen, wenn Sie bei den höheren Kanalfunktionen bleiben. Erinnere dich an Go's Motto: "Teile Speicher durch Kommunikation, kommuniziere nicht durch Teilen von Speicher."

Noch ein Leckerbissen, es gibt eine sehr detaillierte Tour verschiedener Techniken zum Erstellen einer sicheren Karte für die gleichzeitige Nutzung in Mark Summerfields Go Buch .

Um Rob Pikes Folie hervorzuheben, einer der Schöpfer von Go:

  

Parallelität vereinfacht die Synchronisation

     
  • Es ist keine explizite Synchronisation erforderlich
  •   
  • Die Struktur des Programms ist implizit synchronisiert
  •   

Wenn Sie den Weg der Verwendung eines Primitivs wie eines Mutex gehen, ist Ihr Programm komplizierter, da es extrem, extrem schwer zu bekommen ist. Du wurdest gewarnt.

Auch hier ist ein Zitat von der Golang-Seite selbst :

  

Die gleichzeitige Programmierung in vielen Umgebungen wird durch die   Feinheiten, die erforderlich sind, um den korrekten Zugriff auf gemeinsam genutzte Variablen zu implementieren.   Go unterstützt einen anderen Ansatz, bei dem gemeinsame Werte übergeben werden   herum auf Kanälen und in der Tat nie aktiv von getrennt geteilt   Ausführungsfäden. Nur eine Goroutine hat Zugriff auf den Wert at   jede gegebene Zeit. Dieser Ansatz kann zu weit gehen. Referenz zählt   kann am besten getan werden, indem man einen Mutex um eine Integer-Variable, z   Beispiel. Aber als ein High-Level-Ansatz, mit Kanälen zu steuern   Der Zugriff erleichtert das Schreiben klarer, korrekter Programme.

    
Ralph Caraveo 12.08.2013 16:43
quelle
7

Ich würde sagen, Mutexe sind für diese Anwendung in Ordnung. Wickeln Sie sie in einen Typ, damit Sie später Ihre Meinung ändern können. Beachten Sie die Einbettung von sync.RWMutex , wodurch die Sperrung besser wird.

%Vor%

Playground-Link

    
Nick Craig-Wood 12.08.2013 17:35
quelle
3
  • Sie können Sperren für Nachrichtenwarteschlangen nicht verwenden. Dafür gibt es Kanäle.

  • Sie können Sperren nach Kanälen simulieren, aber dafür sind Kanäle nicht geeignet.

  • Verwenden Sie Sperren für den gleichzeitigen sicheren Zugriff auf freigegebene Ressourcen.

  • Verwenden Sie Kanäle für gleichzeitige sichere Nachrichtenwarteschlangen.

Verwenden Sie RWMutex, um Kartenschreibvorgänge zu schützen.

    
zzzz 12.08.2013 17:14
quelle
0

Hier ist ein alternativer kanalbasierter Ansatz, der den Kanal als Mechanismus für den gegenseitigen Ausschluss verwendet:

%Vor%

wo wir die Ressource zunächst in einen gemeinsamen Kanal legen. Dann können die Goroutines diese geteilte Ressource ausleihen und zurückgeben. Im Gegensatz zur Lösung mit RWMutex können sich jedoch mehrere Leser gegenseitig blockieren.

    
dyoo 13.08.2013 02:25
quelle

Tags und Links