181

Goで繰り返しバックグラウンドタスクを実行する方法はありますか? 私はTimer.schedule(task, delay, period)Javaのようなものを考えています。ゴルーチンとTime.sleep()でこれを実行できることはわかっていますが、簡単に停止できるものが欲しいです。

これが私が得たものですが、私には醜く見えます。よりクリーンな/より良い方法はありますか?

func oneWay() {
    var f func()
    var t *time.Timer

    f = func () {
        fmt.Println("doing stuff")
        t = time.AfterFunc(time.Duration(5) * time.Second, f)
    }

    t = time.AfterFunc(time.Duration(5) * time.Second, f)

    defer t.Stop()

    //simulate doing stuff
    time.Sleep(time.Minute)
}
4

7 に答える 7

283

この関数time.NewTickerは、定期的なメッセージを送信するチャネルを作成し、それを停止する方法を提供します。次のように使用します (未テスト):

ticker := time.NewTicker(5 * time.Second)
quit := make(chan struct{})
go func() {
    for {
       select {
        case <- ticker.C:
            // do stuff
        case <- quit:
            ticker.Stop()
            return
        }
    }
 }()

quitチャネルを閉じることでワーカーを停止できます: close(quit).

于 2013-05-09T16:28:50.853 に答える
23

このライブラリをチェックしてください: https://github.com/robfig/cron

以下の例:

c := cron.New()
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
c.AddFunc("@hourly",      func() { fmt.Println("Every hour") })
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.Start()
于 2015-12-08T07:56:44.603 に答える
3

この質問に対するより広い答えとして、Occam でよく使用され、JCSPを介して Java コミュニティに提供されている Lego ブロックのアプローチが考えられるかもしれません。このアイデアについて、Peter Welch による非常に優れたプレゼンテーションがあります。

Go は Occam と同じ通信シーケンシャル プロセスの基礎を使用するため、このプラグ アンド プレイ アプローチは直接 Go に変換されます。

したがって、反復タスクの設計に関しては、チャネルを介してイベント (メッセージまたはシグナル) を交換する単純なコンポーネント (ゴルーチン) のデータフロー ネットワークとしてシステムを構築できます。

このアプローチは構成的です。小さなコンポーネントの各グループは、それ自体がより大きなコンポーネントとして無限に動作できます。複雑な並行システムは理解しやすいブリックから作られているため、これは非常に強力です。

脚注: Welch のプレゼンテーションでは、チャネルに Occam 構文を使用していますそしてこれらは Go のch<-および<-chに直接対応します。

于 2013-05-10T16:49:37.240 に答える