目的
goroutine内で定期的な処理を行いながら,外部からのチャネル受信を待つ,という様な処理をしたい.
方法
time.Ticker
を利用する.
以下のページを参照させていただきました.
https://qiita.com/ruiu/items/1ea0c72088ad8f2b841e
http://text.baldanders.info/golang/ticker/
main.go
package main
import (
"time"
"log"
"sync"
)
func main(){
wg := sync.WaitGroup{}
ch := make(chan struct{})
wg.Add(1)
go func(){
t := time.NewTicker(2 * time.Second) // 2秒おきに通知
defer func (){
wg.Done()
t.Stop()
}()
for {
select{
case <-t.C:
log.Println("2sec interval")
case _, ok := <- ch:
if !ok {
return
}
log.Println("1sec interval")
}
}
}()
for i := 0; i < 10; i ++ {
time.Sleep(time.Second * 1)
ch <- struct{}{}
}
close(ch)
wg.Wait()
}
出力は以下の通り.
出力
2018/10/22 07:57:42 1sec interval
2018/10/22 07:57:43 2sec interval
2018/10/22 07:57:43 1sec interval
2018/10/22 07:57:44 1sec interval
2018/10/22 07:57:45 2sec interval
2018/10/22 07:57:45 1sec interval
ダメだった方法1
time.Sleep()
を利用する方法.当たり前のことだが,default内で処理がブロックしてしまい,channelからの受信がうまくいっていない.
for内部のみ
for {
select{
case _, ok := <- ch:
if !ok {
return
}
log.Println("1sec interval")
default:
log.Println("2sec interval")
time.Sleep(2 * time.Second) //ここで処理がブロック
}
}
出力
2018/10/22 08:21:12 1sec interval
2018/10/22 08:21:12 2sec interval
2018/10/22 08:21:14 1sec interval
2018/10/22 08:21:14 2sec interval
2018/10/22 08:21:16 1sec interval
2018/10/22 08:21:16 2sec interval
ダメだった方法2
time.After ()
を利用.N時刻後にチャネルからメッセージが送られてくるという理解なので,なぜこれで動かないのか不明.
for内部のみ
for {
select{
case <- time.After(2 * time.Second):
log.Println("2sec interval")
case _, ok := <- ch:
if !ok {
return
}
log.Println("1sec interval")
}
}
出力
2018/10/22 08:34:54 1sec interval
2018/10/22 08:34:55 1sec interval
2018/10/22 08:34:56 1sec interval
2018/10/22 08:34:57 1sec interval
2018/10/22 08:34:58 1sec interval