2016-05-28 5 views
0

Gibt es einen Unterschied zwischenIst es wichtig, wo ich den Ticker erstelle?

ticker := time.NewTicker(1 * time.Second) 

go func() { 
    for _ = range ticker.C { 
     fmt.Print("Tick") 
    } 
}() 

time.Sleep(3) 
ticker.Stop() 

und

var ticker *time.Ticker 

go func() { 
    ticker = time.NewTicker(1 * time.Second) 
    for _ = range ticker.C { 
     fmt.Print("Tick") 
    } 
}() 

time.Sleep(3) 
ticker.Stop() 

in Bezug auf Thread-Sicherheit, vor allem, wenn die Arbeit in der Funktion dauert länger als eine Periode des tick?

ich frage, weil sie (wenn die Ticker Anhalten ist nicht erforderlich) diese auf

verkürzt werden kann
go func() { 
    for ticker := time.NewTicker(1 * time.Second) ;; <-ticker.C { 
     fmt.Print("Tick") 
    } 
}() 

während erstere nicht. Diese Form hat den zusätzlichen Vorteil, dass der erste Tick sofort ausgelöst wird.

+0

Es gibt keinen Unterschied tatsächlich. Es ist jedoch eine gute Methode, die erforderlichen Variablen aus einem umschließenden Gültigkeitsbereich als Parameter an Goroutines zu übergeben. –

Antwort

2

Die zweite Version des Codes ist falsch: Es hat eine Race Condition.

var ticker *time.Ticker 

go func() { 
    ticker = time.NewTicker(1 * time.Second) 
    for _ = range ticker.C { 
     fmt.Print("Tick") 
    } 
}() 

time.Sleep(3) 
ticker.Stop() 

Es gibt keine Synchronisation zwischen der Zuordnung zu ticker innerhalb des goroutine und die Verwendung von ticker im ticker.Stop() Anruf.

In der Praxis wird dies wegen der langen time.Sleep(3) fast immer harmlos sein, aber solche Rennen sollten möglichst vermieden werden, denn auch wenn sie heute harmlos sind, können sie später Probleme verursachen. Zum Beispiel, wenn Sie anstelle von Sleep Code haben, der eine variable Menge an Zeit benötigt, sehen Sie möglicherweise keine Zeiger-Panics, wenn dieser Code sehr kurz ist.

Aus diesem Grund würde ich immer die erste Version Ihres Codes (der, der die ticker außerhalb der Goroutine erstellt) verwenden.

Die dritte Version des Codes (wo die ticker vollständig innerhalb der Goroutine verwendet wird) ist auch gut. Ich würde definitiv diese kürzere Version des Codes verwenden, wo der Ticker innerhalb der Goroutine definiert wird, wenn das möglich ist. Die Kürze des Codes ist nett, aber ich mag auch, dass der Code außerhalb des Tickers überhaupt nicht angezeigt wird, so dass es für den Leser des Codes leicht ist, den Umfang des Tickers zu verstehen.

+0

Sie sagen "die dritte Version ist auch gut". Das bedeutet, dass der Ticker richtig funktioniert, auch wenn er in der gleichen Goroutine definiert ist, die die Arbeit ausführt? – AndreKR

+0

@AndreKR ja, Variablen in der gleichen Goroutine zu verwenden, die sie definiert sind, ist normal. Es kann helfen, zu verstehen, dass alle Programme mindestens eine Goroutine haben - die, die Ihren Code in main ausführt! –

+0

Ich dachte, vielleicht, wenn die Goroutine beschäftigt ist, bekommt der Ticker irgendwie keine Chance, den nächsten Tick an den Kanal zu senden, aber bei einem zweiten Gedanken, der keinen Sinn ergibt, braucht der Ticker in jedem Fall eine andere interne Routine. – AndreKR

Verwandte Themen