Wenn ich Kanäle richtig verwende, sollte ich Mutexe verwenden müssen, um gegen gleichzeitigen Zugriff zu schützen?Wenn ich Kanäle richtig verwende, sollte ich Mutexe verwenden?
Antwort
Sie benötigen keinen Mutex, wenn Sie Kanäle richtig verwenden. In einigen Fällen könnte eine Lösung mit Mutex jedoch einfacher sein.
Stellen Sie nur sicher, dass die Variable (n), die die Kanalwerte enthalten, richtig initialisiert werden, bevor mehrere Gaborutinen versuchen, auf die Kanalvariablen zuzugreifen. Sobald dies geschehen ist, ist der Zugriff auf die Kanäle (z. B. das Senden von Werten an oder das Empfangen von Werten von ihnen) sicher durch das Design.
Belege, die mit Referenzen (Hervorhebungen von mir hinzugefügt):
Ein einzelner Kanal kann in send statements, receive operations verwendet werden, und ruft den integrierten Funktionen
cap
undlen
von einer beliebigen Anzahl von Goroutinen ohne weitere Synchronisation. Kanäle fungieren als First-In-First-Out-Warteschlangen. Wenn zum Beispiel eine Goroutine Werte auf einem Kanal sendet und eine zweite Goroutine sie empfängt, werden die Werte in der gesendeten Reihenfolge empfangen.
Effective Go: Concurrency: Share by communicating
Concurrent programming in vielen Umgebungen wird durch die Feinheiten erschwert erforderlich korrekten Zugriff auf gemeinsam genutzte Variablen zu implementieren. Go unterstützt eine andere Herangehensweise, bei der gemeinsame Werte auf Kanälen weitergegeben und tatsächlich niemals von separaten Ausführungsthreads gemeinsam genutzt werden. Nur eine Goroutine hat zu jedem Zeitpunkt Zugriff auf den Wert. Datenrennen können nicht auftreten. Um diese Art des Denkens zu fördern, haben wir es auf einen Slogan reduziert:
Kommunizieren Sie nicht, indem Sie Speicher teilen; Stattdessen teilen Sie Speicher durch Kommunikation.
Dieser Ansatz kann zu weit gehen. Referenzzählungen können am besten durchgeführt werden, indem man beispielsweise einen Mutex um eine Integer-Variable legt. Aber als ein Ansatz auf höherer Ebene macht die Verwendung von Kanälen zur Zugriffskontrolle das Schreiben klarer, korrekter Programme einfacher.
Dieser Artikel ist auch sehr hilfreich: The Go Memory Model
zitierte auch aus dem Paket doc von sync
:
Package Sync Basissynchronisations Primitiven wie mutual exclusion Sperren zur Verfügung stellt. Anders als die Once- und WaitGroup-Typen sind meist für die Verwendung von Low-Level-Bibliotheksroutinen vorgesehen. Die Synchronisation auf höherer Ebene erfolgt besser über Kanäle und Kommunikation.
- 1. Sollte ich die addslashes-Funktion verwenden, wenn ich PDO verwende?
- 2. Wenn ich UUIDs verwende, sollte ich auch AUTO_INCREMENT verwenden?
- 3. Wie verwende ich sync.Cond richtig?
- 4. Wie verwende ich SDL_Threads richtig?
- 5. Wie verwende ich gluLookAt richtig?
- 6. Wenn ich GCD verwende, sollte ich @autorelease Pool
- 7. ReactiveUI Wie verwende ich WhenAnyObservable richtig?
- 8. Wie verwende ich dispatch_sync richtig?
- 9. Wie verwende ich ManagedObjectID richtig?
- 10. Wie verwende ich HashMap richtig?
- 11. Wie verwende ich PropertyValueFactory richtig?
- 12. Wie verwende ich PUSH richtig?
- 13. Wie verwende ich Build Tags richtig?
- 14. Würde ich ein ORM verwenden, wenn ich Stored Procedures verwende?
- 15. Sollte ich einen Wert verschieben, den ich nicht mehr verwende?
- 16. Wie verwende ich Java Executor richtig?
- 17. Wie verwende ich diesen Iterator richtig?
- 18. MVC3 - Wie verwende ich @ html.checkbox richtig?
- 19. Flexslider funktioniert nicht richtig, wenn ich ng-repeat verwende
- 20. Wie verwende ich die StateT Monade richtig?
- 21. Redis: wie (oder sollte) ich pubsub Kanäle löschen
- 22. Wie verwende ich argparse subparsers richtig?
- 23. Sollte ich jQuery.inArray() verwenden?
- 24. Sollte ich Fremdschlüssel verwenden?
- 25. Sollte ich Bootstrap verwenden?
- 26. Sollte ich jQuery.each() verwenden?
- 27. Sollte ich sonst verwenden, wenn ich nicht brauche?
- 28. Warum sollte ich WndProc verwenden, wenn ich Formularereignisse habe?
- 29. Welchen Fehlerwert sollte ich verwenden?
- 30. Wie sollte ich richtig mit Mungo bevölkern?
Während dies eine großartige allgemeine Richtlinie ist, denke ich, dass wir wirklich betonen müssen "Dieser Ansatz kann zu weit gefasst werden." Vorbehalt. Ich habe eine Menge schauerlich komplizierten Codes daraus gesehen, mit einer Unordnung von Reaktorschleifen und Nachrichtenübergabe, wo ein einfacher Mutex genügen würde. Wie ich gerne über das Problem nachdenke: Wenn Sie versuchen, einen "gegenseitigen Ausschluss" um eine * einzige * logische Ressource zu erreichen, dann möchten Sie wahrscheinlich einen Mutex.Wenn Sie versuchen, Goroutines zu koordinieren und Synchronisationspunkte bereitzustellen, dann möchten Sie Kanäle. (Alles dazwischen kommt mit Erfahrung) – JimB