Gewusst wie: implementieren Sie einen Zähler bei der Verwendung von golang die goroutine?
Ich versuche zu machen ein queue struct, dass die push und pop Funktionen.
Ich 10 threads schieben und weitere 10 threads pop-Daten, nur wie ich in dem code unten.
Fragen :
1. Ich muss ausgedruckt, wie viel ich habe geschoben/aufgetaucht, aber ich weiß nicht, wie das zu tun.
2. Ist es irgendwie beschleunigen mein code ? der code ist zu langsam für mich.
package main
import (
"runtime"
"time"
)
const (
DATA_SIZE_PER_THREAD = 10000000
)
type Queue struct {
records string
}
func (self Queue) push(record chan interface{}) {
//need push counter
record <- time.Now()
}
func (self Queue) pop(record chan interface{}) {
//need pop counter
<- record
}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
//record chan
record := make(chan interface{},1000000)
//finish flag chan
finish := make(chan bool)
queue := new(Queue)
for i:=0; i<10; i++ {
go func() {
for j:=0; j<DATA_SIZE_PER_THREAD; j++ {
queue.push(record)
}
finish<-true
}()
}
for i:=0; i<10; i++ {
go func() {
for j:=0; j<DATA_SIZE_PER_THREAD; j++ {
queue.pop(record)
}
finish<-true
}()
}
for i:=0; i<20; i++ {
<-finish
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es ein paar Dinge, die Sie beheben sollten.
Den Methoden, die in der Warteschlange geben sollte-Zeiger-Empfänger. Ansonsten, jede Methode
rufen Sie erstellt eine Kopie der aktuellen queue-Typ und die änderungen in die Warteschlange Felder
nicht weiter über die Methode sich selbst aufrufen.
Warten alle Routinen zu beenden, kann durchgeführt werden, indem ein
sync.WaitGroup
. Dieseist speziell, was es für entworfen wurde.
Aufrechterhaltung einer thread-sicheren push - /pop-counter innerhalb der queue-Typ kann getan werden, indem
mit der
sync/atomic
Paket.So weit wie Geschwindigkeit geht, aus deinem Beispiel bin ich mir nicht ganz sicher, was Sie versuchen zu erreichen. Alle Verbesserungen kommen könnte, wenn du das nochmal ein wenig.
Hier ist ein Beispiel, das ich geändert, aus dem code:
wg.Add(1)
defer.wg.Done()
in jeder erstellt goroutine?wg.Add(1)
in jede goroutine ist im Prinzip machbar. Es sollte aber beachtet werden, dass es keine Garantie dafür, dass die goroutine wird für die Ausführung geplant werden, bevor der Aufruf von thread erreicht, diewg.Wait()
Teil. In einigen seltenen Fällen könnte dies bedeuten, dass dieWaitGroup
counter wurde noch nicht erhöht, und der Aufruf vonwg.Wait()
vorzeitig abgeschlossen. Dies stellt eine race-Bedingung und sollten daher vermieden werden. Sie können sicher aufrufenwg.Add(1)
Recht, vor dem starten einer bestimmten goroutine obwohl.Antwort zu Frage 1: Wie jimt vorgeschlagen, sync/atomic-Funktionen für atomar Aktualisierung eines Zählers, die für Sie nützlich sein kann.
Antwort zu Frage 2: Verringern Sie den Wert, der DATA_SIZE_PER_THREAD, oder besser noch, verwenden Sie das Programm
produziert die gleiche Ausgabe wie das Programm in ein effektiver Weg.
Aber im ernst, ich verstehe Sie geschrieben haben, ein kleines Programm zu erkunden, einige Konzepte. Ihr Programm enthält eine Reihe von Fragen allerdings. Dies ist nicht die Zeit sich sorgen zu machen über die Geschwindigkeit, es ist die Zeit zu lernen, einige grundlegende Konzepte.