time.NewTickerを用いた処理ではよく、以下のような構文が紹介されています。
go
1go func() { 2 t := time.NewTicker(3 * time.Second) // 3秒おきに通知 3 for { 4 select { 5 case <-t.C: 6 // 3秒経過した。ここで何かを行う。 7 } 8 } 9 t.Stop() // タイマを止める。 10}()
go
1go func() { 2 t := time.NewTicker(3 * time.Second) 3 defer t.Stop() 4 for { 5 select { 6 case <-t.C: 7 // 3秒経過した。ここで何かを行う。 8 } 9 } 10 // t.Stop() // タイマを止める。 11}()
一見すると特に違和感はないように思うのですが、以下のようなコードを書き確認したところ、そもそもdeferが実行されていないように思います。
go
1package main 2 3import( 4 "fmt" 5 "time" 6) 7 8var ( 9 done = false 10) 11 12func main() { 13 14 fmt.Println("START.") 15 16 go callFunction() 17 18 for !done { 19 time.Sleep(time.Second) 20 fmt.Println("wait.") 21 } 22 23 fmt.Println("END.") 24 25} 26 27func callFunction() { 28 29 fmt.Println("START callFunction.") 30 31 t := time.NewTicker(3 * time.Second) 32 33 defer t.Stop() 34 defer fmt.Println("call defer.") 35 36 fmt.Println("POINT:A.") 37 38 for { 39 select { 40 case <-t.C: 41 fmt.Println("tick.") 42 done = true 43 } 44 } 45 46 fmt.Println("END callFunction.") 47 48}
このコードを実行すると以下のような出力となります。
START.
START callFunction.
POINT:A.
wait.
wait.
tick.
wait.
END.
当然ですが、time.NewTickerを使わないケースでは想定通りにdeferが実行されます。
go
1package main 2 3import( 4 "fmt" 5 "time" 6) 7 8var ( 9 done = false 10) 11 12func main() { 13 14 fmt.Println("START.") 15 16 go callFunction() 17 18 for !done { 19 time.Sleep(time.Second) 20 fmt.Println("wait.") 21 } 22 23 fmt.Println("END.") 24 25} 26 27func callFunction() { 28 29 fmt.Println("START callFunction.") 30 31 defer fmt.Println("call defer.") 32 33 time.Sleep(3 * time.Second) 34 35 done = true 36 37 fmt.Println("END callFunction.") 38 39} 40
上記の実行結果は以下の様になります。
START.
START callFunction.
wait.
wait.
END callFunction.
call defer.
wait.
END.
なぜtime.NewTickerを使ったケースではdeferが実行されないのでしょうか。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/03/08 20:54