2017-11-18 2 views
-4

Ich versuche verwenden "sync.mutex" schützen meine Funktion, aber ich stellte fest, dass die Sperre immer noch den Anrufer verwendet, um es zu zerstören.In Golang, wie kann ich mein eigenes Schloss vor der Zerstörung durch den Anrufer schützen?

var mutex sync.mutex 

Dies ist Fehler:

//caller use 
func a() { 
    for i := 0; i < 10; i++ { 
     go b(i) 
    } 
} 

//My func 
func b(i int) { 
    mutex.Lock() 
    fmt.Println(i) 
    mutex.Unlock() 
} 

dieser Erfolg ist, aber meine Kapselungsmethode zerstört:

//caller use 
func a() { 
    for i := 0; i < 10; i++ { 
     mutex.Lock() 
     go b(i) 
    } 
} 

//my func 
func b(i int) { 
    fmt.Println(i) 
    mutex.Unlock() 
} 

Dank

+0

ein Mutex sollte gesperrt und entsperrt aus dem gleichen Codeblock, wenn überhaupt möglich. – Adrian

Antwort

1

The Go Programming Language Specification

Exported identifiers

An identifier may be exported to permit access to it from another package. An identifier is exported if both:

  • the first character of the identifier's name is a Unicode upper case letter (Unicode class "Lu"); and
  • the identifier is declared in the package block or it is a field name or method name.

All other identifiers are not exported.

Setzen Sie die Funktion in einem eigenen Paket und exportieren Sie die Stummschaltung nicht x. Beispielsweise.

package b 

import (
    "fmt" 
    "sync" 
) 

var mutex sync.Mutex 

func B(i int) { 
    mutex.Lock() 
    fmt.Println(i) 
    mutex.Unlock() 
} 

zu verwenden,

package a 

import "b" 

func a() { 
    for i := 0; i < 10; i++ { 
     go b.B(i) 
    } 
} 
+0

Danke, ich habe vielleicht von sync.Cond.wait() getäuscht. Wenn goroutines wartet, blockiert es andere goroutines nicht. Ich werde meinen Code ändern, versuch es erneut. – tiango

+0

Kann nicht, ich habe es versucht. Das gleiche ist nicht sicher, es ist eine seltsame Sache.Vielleicht sollte ich mehr eingehende Studie Mutex und Goroutines gehen – tiango

+2

@tiango: Eine übliche Methode, um goroutines zu verwalten ist eine 'sync.WaitGroup' mit' Add', 'Wait', und 'Fertig'-Methoden. Siehe den Go-Tour-Abschnitt über Nebenläufigkeit: https://tour.golang.org – peterSO

0

Im ersten Beispiel werden alle Anrufe zu go b(i) in a ‚s-Schleife genannt, aber die Schleife beendet werden kann, bevor eine der goroutines eine Chance haben, fang an, also wenn die Hauptreklame zurückkehrt, dann hören alle diese Goroutinen auf.

Im zweiten Beispiel wird der Mutex gesperrt und nicht entsperrt, bis Unlock in jeder der Goroutinen aufgerufen wird. Das Ergebnis ist, dass die Aufrufe vollständig sequenziell sind, da jede Iteration der Schleife in a nicht gestartet werden kann, bis die letzte Routine b endet und Unlock aufruft.

Eine bessere Praxis in Go wäre für Ihre b-Funktion zusammen mit der Anzahl übergab in einem Zeiger auf den Mutex zu nehmen, so in Ihrem ursprünglichen Beispiel es aussehen würde:

//caller use 
func a() { 
    var wg sync.WaitGroup 
    for i := 0; i < 10; i++ { 
     wg.Add(1) 
     go func() { 
      defer wg.Done() 
      b(&mutex, i) 
     }() 
    } 
    wg.Wait() 
} 

//My func 
func b(mutex *sync.Mutex, i int) { 
    mutex.Lock() 
    fmt.Println(i) 
    mutex.Unlock() 
} 

Welche entfernen würde Vertrauen auf eine globale Variable und auch garantieren, dass alle Aufrufe an b den exakt gleichen Mutex verwenden, da wir einen Zeiger auf einen Mutex

+0

Wird das nicht das Schloss zerstören? 'func a() {für i: = 0; ich <10; i ++ {gehe b (& mutex, i); mutex.Unlock()}} ' – peterSO

+0

@Andy Haskell Sie haben Recht. Andere Frage, "sync.Cond.wait()" nicht andere Gockeln blockieren. Ich denke, es ist eine seltsame Sache. Vielleicht sollte ich mehr eingehende Studie Mutex und Goroutines gehen. Warum kann der Mutex die Sicherheit der Methode nicht garantieren? Wie kann ich das Golang-Schloss besser verstehen? – tiango

+0

@tiango Ich habe noch nie einen sync.Cond verwendet. Ich benutze Go auf dem Job und die Teile der Nebenläufigkeit, die ich regelmäßig verwende, sind 'Mutex',' RWMutex', 'WaitGroup' und Kanäle (die intern einen Mutex verwenden). Dies ist ein guter Beitrag zum Verständnis von WaitGroups https://medium.com/@matryer/very-basic-concurrency-for-beginners-in-go-663e63c6ba07 und dieser Beitrag hat ein Beispiel für Mutexe https://gobyexample.com/ Mutexe. Wo lernst du gerade? Und hast du Nebenläufigkeit in anderen Sprachen genutzt? –

Verwandte Themen