2

Ticker を使用して、実行時間の長いデーモン プロセスの正常な終了を実装することは可能ですか? ここで他の関連スレッドを読んで、メモリリークを避けるために常にチャネルを閉じる必要がありますが、これをデーモンモードで実行すると (daemonize を使用て golang の外部でデーモン操作を処理するとしましょう)、実際には方法がありませんプロセスが終了する前に集合的なクリーンアップを行うため。何か不足していない限り、Golang でこれを行う代替/より良い方法があるかどうかを尋ねるためにここにいます

func main() {
  ticker := time.NewTicker(Interval)
  workers := make(chan bool, 1)

  for t := range ticker.C {
    select {
      case <- ticker.C:
        log.Println("Scheduled task is triggered.", t)
        go runWorker(workers)
      case <- workers:
        log.Println("Scheduled task is completed.")
        // can't return, it needs to be continue running
    }
  }
}
4

2 に答える 2

1

メイン関数はティッカー チャネルを 2 回読み取ります。1 回目はティックの後、次に別のティック後は続行しますが、これはおそらくあなたが望むものではありません (Interval が 30 分である場合、60 分ごとにゴルーチンを実行するだけです)。これはより良いアプローチです:

func main() {
  ticker := time.NewTicker(Interval)
  workers := make(chan bool, 1)

  for {
    select {
      case <- ticker.C:
        log.Println("Scheduled task is triggered.", t)
        go runWorker(workers)
      case <- workers:
        log.Println("Scheduled task is completed.")
        // can't return, it needs to be continue running
    }
  }
}

これにより、各間隔の後にゴルーチンが作成され続けます。ループが終了するまで、このチャネルを閉じる必要はありません。アプリケーションが終了しただけであれば、チャネルは安全にクリーンアップされます。ループを早期に停止する必要がある場合は、ループを終了する前に ticker.Stop() を呼び出すようにしてください。

間隔をあけてゴルーチンを 1 回だけ実行したい場合は、time.AfterFunc を使用します

于 2014-08-05T16:35:51.377 に答える