2016-01-27 6 views
5

यह गोलांग कोड एकाधिक समय के बीच क्यों चयन नहीं करता है। चैनलों के बाद काम करते हैं?यह गोलांग कोड एकाधिक समय के बीच क्यों चयन नहीं करता है। चैनलों के बाद काम करते हैं?

नीचे कोड देखें। 'टाइमआउट' संदेश कभी जारी नहीं किया जाता है। क्यूं कर?

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    count := 0 
    for { 
     select { 
     case <-time.After(1 * time.Second): 
      count++ 
      fmt.Printf("tick %d\n", count) 
      if count >= 5 { 
       fmt.Printf("ugh\n") 
       return 
      } 
     case <-time.After(3 * time.Second): 
      fmt.Printf("timeout\n") 
      return 
     } 
    } 
} 

भागो यह खेल का मैदान पर: http://play.golang.org/p/1gku-CWVAh

आउटपुट:

tick 1 
tick 2 
tick 3 
tick 4 
tick 5 
ugh 
+0

संभावित डुप्लिकेट [golang समय समाप्ति चैनलों के साथ निष्पादित नहीं किया गया है] (http://stackoverflow.com/questions/34894927/golang-timeouts-is-not-executed-with-channels) – icza

उत्तर

10

क्योंकि time.After, एक समारोह है इसलिए हर यात्रा पर यह एक नया चैनल देता है। आप इस चैनल सभी पुनरावृत्तियों के लिए एक ही होना चाहते हैं, तो आप इसे पाश से पहले बचाने चाहिए:

timeout := time.After(3 * time.Second) 
for { 
    select { 
    //... 
    case <-timeout: 
     fmt.Printf("timeout\n") 
     return 
    } 
} 

खेल का मैदान: http://play.golang.org/p/muWLgTxpNf

+0

वाह! मैं कई चैनल बना रहा था! धन्यवाद! – Everton

3

यहां तक ​​कि @Ainar-G पहले से ही उत्तर प्रदान कर चुका है, एक और संभावना है कि प्रत्येक सेकंड पर एक समय टिक बनाने के लिए time.Tick(1e9) का उपयोग करें और फिर निर्दिष्ट अवधि के बाद timeAfter चैनल सुनें।

package main 

import (
    "fmt" 
    "time" 
) 

func main() { 
    count := 0 
    timeTick := time.Tick(1 * time.Second) 
    timeAfter := time.After(5 * time.Second) 

    for { 
     select { 
     case <-timeTick: 
      count++ 
      fmt.Printf("tick %d\n", count) 
      if count >= 5 { 
       fmt.Printf("ugh\n") 
       return 
      } 
     case <-timeAfter: 
      fmt.Printf("timeout\n") 
      return 
     } 
    } 
} 
की
संबंधित मुद्दे