Go에서 반복적 인 백그라운드 작업을 수행 할 수있는 방법이 있습니까? Timer.schedule(task, delay, period)
Java 와 같은 것을 생각하고 있습니다. 나는 goroutine으로이 작업을 수행 할 수 있다는 것을 알고 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)
}
답변
이 기능 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)
..
답변
어때요?
package main
import (
"fmt"
"time"
)
func schedule(what func(), delay time.Duration) chan bool {
stop := make(chan bool)
go func() {
for {
what()
select {
case <-time.After(delay):
case <-stop:
return
}
}
}()
return stop
}
func main() {
ping := func() { fmt.Println("#") }
stop := schedule(ping, 5*time.Millisecond)
time.Sleep(25 * time.Millisecond)
stop <- true
time.Sleep(25 * time.Millisecond)
fmt.Println("Done")
}
답변
틱 시프 팅에 신경 쓰지 않고 (각 실행에 얼마나 오래 걸 렸는지에 따라) 채널을 사용하지 않으려는 경우 기본 범위 기능을 사용할 수 있습니다.
즉
package main
import "fmt"
import "time"
func main() {
go heartBeat()
time.Sleep(time.Second * 5)
}
func heartBeat() {
for range time.Tick(time.Second * 1) {
fmt.Println("Foo")
}
}
답변
이 라이브러리를 확인하십시오 : 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()
답변
이 질문에 대한 더 넓은 대답은 Occam에서 자주 사용되며 JCSP 를 통해 Java 커뮤니티에 제공되는 레고 브릭 접근법을 고려할 수 있습니다 . 피터 웰치 (Peter Welch) 는이 아이디어에 대해 매우 훌륭한 발표를 합니다.
Go는 Occam과 동일한 커뮤니 케이 팅 순차 프로세스 기본 사항을 사용하므로이 플러그 앤 플레이 방식은 Go로 직접 변환됩니다.
따라서 반복적 인 작업을 설계 할 때 채널을 통해 이벤트 (예 : 메시지 또는 신호)를 교환하는 간단한 구성 요소 (고 루틴)의 데이터 흐름 네트워크로 시스템을 구축 할 수 있습니다.
이 접근 방식은 구성 적입니다. 각 소규모 구성 요소 그룹은 그 자체로 더 큰 구성 요소로 작동 할 수 있습니다. 복잡한 동시 시스템은 이해하기 쉬운 벽돌로 만들어지기 때문에 매우 강력 할 수 있습니다.
각주 : Welch의 프레젠테이션에서 그는 채널에 Occam 구문을 사용합니다 . 그리고 ? 이들은 Go의 ch <- 및 <-ch 에 직접 대응됩니다 .
답변
다음 코드를 사용합니다.
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println("\nToday:", now)
after := now.Add(1 * time.Minute)
fmt.Println("\nAdd 1 Minute:", after)
for {
fmt.Println("test")
time.Sleep(10 * time.Second)
now = time.Now()
if now.After(after) {
break
}
}
fmt.Println("done")
}
더 간단하고 나에게 잘 작동합니다.