2016-08-29 4 views
2

나는 Golang 루틴의 간단한 코드를 이해하려고 노력 해요 :골란에서 'time.After'와 'default'를 어떻게 사용할 수 있습니까?

package main 

import (
    "fmt" 
    "time" 
) 

func sleep(seconds int, endSignal chan<- bool) { 
    time.Sleep(time.Duration(seconds) * time.Second) 
    endSignal <- true 
} 

func main() { 
    endSignal := make(chan bool, 1) 
    go sleep(3, endSignal) 
    var end bool 

    for !end { 
     select { 
     case end = <-endSignal: 
      fmt.Println("The end!") 
     case <-time.After(5 * time.Second): 
      fmt.Println("There's no more time to this. Exiting!") 
      end = true 
     } 
    } 

} 

괜찮지 만 내가 왜이 "선택"블록에 간단한 기본을 사용할 수 없습니다? 이런 식으로 뭔가 :

❯ go run goroutines-timeout.go 
No end signal received! 
No end signal received! 
No end signal received! 
No end signal received! 
... 
The end! 

을 그리고 그 이유를 이해할 수 없다 :

for !end { 
    select { 
    case end = <-endSignal: 
     fmt.Println("The end.") 
    case <-time.After(4 * time.Second): 
     fmt.Println("There's no more time to this. Exiting!") 
     end = true 
    default: 
     fmt.Println("No end signal received.") 
    } 
} 

는이 출력을 얻을 수 있습니다.

+0

각 그렇지. 무슨 일이 일어날 지 설명해 주시겠습니까? – JimB

+0

'time.After'의 시간이 끝나지 않는 동안'default'가 이것을 할 것으로 예상합니다. –

+0

나는 그것을 이해하지 못한다. 디폴트의 ​​케이스가 취해지기 (위해) 때문에,'time.After' 케이스는 실행되지 않습니다. – JimB

답변

3

time.After(4 * time.Second)을 실행할 때마다 새 타이머 채널을 만듭니다. select 문은 이전 반복에서 선택한 채널을 기억할 수 없습니다. 또한 비동기식 작업을 수행하여 바쁜 루프로 바꾸어 select 문을 막았습니다.

당신이 필요로하는 것은 당신이 관심이있는 두 개의 채널 주위에 간단한 선택입니다. 그것은 전혀 루프 할 필요가 없습니다.

https://play.golang.org/p/jb4EE8e6cw

당신이 정말로 같은 하나가 선택 될 수 있도록, 여러 번 폴링 루프의 외부 타이머를 확인하려면

select { 
case <-endSignal: 
    fmt.Println("The end!") 
case <-time.After(4 * time.Second): 
    fmt.Println("There's no more time to this. Exiting!") 
} 
이 무엇`기본 반복

timeout := time.After(5 * time.Second) 
pollInt := time.Second 

for { 
    select { 
    case <-endSignal: 
     fmt.Println("The end!") 
     return 
    case <-timeout: 
     fmt.Println("There's no more time to this. Exiting!") 
     return 
    default: 
     fmt.Println("still waiting") 
    } 
    time.Sleep(pollInt) 
} 
+0

감사합니다. 지금 받으 셨습니다. –

관련 문제