Das Entfernen Logik korrekt ist (die Ausgabe auch dies bestätigt). Das Problem ist der Mangel an Synchronisation zwischen mehreren goroutines (Ihre Frage sagt nichts darüber).
Du hat gesagt (in Ihrem Kommentar), dass Sie diese zuerst mit 1 goroutine erhalten arbeiten wollen, und später mit Synchronisation befassen. Aber Ihr Code verwendet bereits mehrere goroutines, so können Sie diesen Luxus nicht haben kann:
//Let a goroutine Handle the connection
go handleConnection(conn)
Mehrere goroutines sind Lesen und Schreiben der Room.Visitors
Scheibe, so haben Sie keine andere Wahl, als den Zugriff darauf zu synchronisieren.
wäre ein Beispiel sync.RWLock
zu verwenden:
utils.go
:
type Room struct {
Name string
Visitors []net.Conn
mux sync.RWLock
}
func (r *Room) Leave(c net.Conn) {
r.mux.Lock()
defer r.mux.Unlock()
for i, v := range r.Visitors {
//found the connection we want to remove
if c == v {
fmt.Printf("Before remove %v\n", r.Visitors)
r.Visitors = append(r.Visitors[:i], r.Visitors[i+1:]...)
fmt.Printf("After remove %v\n", r.Visitors)
return
}
}
}
, wenn auch andere Code Room.Visitors
berührt, auch den Code sperren (Sie RWMutex.RLock()
verwenden können, wenn Sie es nur gerade lesen) .
Ebenso müssen Sie den Zugriff auf alle Variablen synchronisieren, die von mehreren goroutines gelesen/geändert werden.
berücksichtigen auch das Element Nullung, die nach der Entfernung befreit ist, sonst die darunter liegende Array wird noch diesen Wert halten, den gargabe Kollektor verhinderte freie Speicher, um richtig durch sie verwendet. Weitere Informationen zu diesem Thema finden Does go garbage collect parts of slices?
Das Entfernen Logik korrekt ist (die Ausgabe bestätigt auch diese). Das Problem könnte das Fehlen oder die falsche Synchronisierung zwischen mehreren goroutines sein (Ihre Frage sagt nichts darüber aus), oder es gibt andere Probleme in anderen Teilen Ihres Codes, die Sie nicht veröffentlicht haben. – icza
Es ist wahr, dass es nicht gemacht Anstrengung, um sicherzustellen, das mit mehreren goroutines funktioniert, aber ich dachte, sie es mit einem einzigen sicherzustellen Arbeit und Parallelität Überprüfung später hinzufügen, wenn es für einen Thread funktioniert (vielleicht ist dies eine schlechte Haltung) . Ich habe den ganzen Code in einem [gist] (https: //gist.github.com/Oliv95/f79c97cc7d0cba8a1fa3536a5e3caa7a) Wenn Sie die Zeit haben, zu suchen –