LoginSignup
19
20

More than 5 years have passed since last update.

Golangで周期的に実行するときのパターン

Last updated at Posted at 2018-01-22

(contextを使ってキャンセルするパターンを追記しました。)

周期的な実行のトリガーにはtime.Tickerを使用します。
例えば、doPeriodically()を100msec間隔で実行したいときは以下のようにします。

package main

import (
    "log"
    "time"
)

func main() {
    log.SetFlags(log.Lmicroseconds)
    ticker := time.NewTicker(time.Millisecond * 100)
    defer ticker.Stop()
    count := 0
    for {
        select {
        case <-ticker.C:
            log.Printf("count=%d\n", count)
            count++
            doPeriodically()
        }
    }
}

func doPeriodically() {
    /* do something */
}

2018.2.16 追記

defer ticker.Stop() を追加しました
この例ではあってもなくても変わらないのですが、forループを何かの条件で抜けるようにしたときには必要になるので。

参考

もっといい記事をこれ書いた後で見つけてしまいました。
Goで一定周期で何かを行う方法

contextによるキャンセル付き (2018.3.13 追記)

func doPeriodically(t time.Time) {
    /* do something */
}

func periodicLoop(ctx context.Context, interval time.Duration) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()
    doPeriodically(time.Now())
    for {
        select {
        case <-ctx.Done():
            return
        case t := <-ticker.C:
            doPeriodically(t)
        }
    }
}

mainでは以下のようにctxを作成して、periodicLoopに渡し、止めたいときにcancel()を呼びます。

func main() {
    ...

    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()
    go periodicLoop(ctx, 2*time.Second)

    /* call cancel() to stop */
}
19
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
20