如果已经 运行,则不应执行代码
Ticker should not execute if already running
我有一些功能必须定期 运行。我为此使用了自动收报机。但是如果ticker已经是运行ning了,时间间隔又过了,应该不会再执行了。
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(3*time.Second)
flag := 0
defer ticker.Stop()
for {
select {
case t := <-ticker.C:
flag = flag + 1
if (flag % 2 ==0 ) {
time.Sleep(time.Second*4)
}
fmt.Println("Current time: ", t)
}
}
}
https://play.golang.org/p/2xV2MYInn4I
在操场上,自动收报机每 3 秒打印一次,但自动收报机每均匀转动一次,作业花费的时间比间隔时间长。我希望它不会 运行 然后放弃那些滴答声。
我该怎么做?
行情通道已缓冲,这就是为什么您可能会一个接一个地看到多个触发器。您可以通过简单地将代码的值传输到无缓冲通道来防止这种情况(另请注意,从代码接收到的 time.Time 值不是当前时间,而是最后一个报价的时间):
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan time.Time) // unbuffered
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
go func() {
for t := range ticker.C {
select {
case c <- t:
default:
}
}
}()
for flag := 0; flag < 8; flag++ {
<-c
if flag%2 == 0 {
time.Sleep(time.Second * 4)
}
fmt.Println("Current time: ", time.Now())
}
}
// Output:
// Current time: 2020-02-19 12:21:57.095433032 +0100 CET m=+3.000213350
// Current time: 2020-02-19 12:22:04.095585208 +0100 CET m=+10.000365520
// Current time: 2020-02-19 12:22:06.095363327 +0100 CET m=+12.000143680
// Current time: 2020-02-19 12:22:13.095605268 +0100 CET m=+19.000385598
// Current time: 2020-02-19 12:22:15.095371885 +0100 CET m=+21.000152174
// Current time: 2020-02-19 12:22:22.095537562 +0100 CET m=+28.000317857
// Current time: 2020-02-19 12:22:24.095431317 +0100 CET m=+30.000211625
// Current time: 2020-02-19 12:22:31.095524308 +0100 CET m=+37.000304595
在同一个 goroutine 中休眠只会延迟执行。 ticker 同时在一个单独的 goroutine 中运行。因此,即使您使用全局变量来维护执行状态 - 它也不会在睡眠时为您提供所需的结果。然而,将整个 "sleeping" 迁移到一个单独的 goroutine 中会产生:
package main
import (
"fmt"
"time"
)
type Tick struct {
ticker *time.Ticker
executing bool
}
func somethingYouWantToDo(tick *Tick, flag *int, t time.Time) {
if tick.executing {
return
}
tick.executing = true
*flag = *flag + 1
if (*flag % 2 ==0 ) {
time.Sleep(time.Second*4)
}
fmt.Println("Current time: ", t)
tick.executing = false
}
func main() {
tick := &Tick{
ticker: time.NewTicker(3*time.Second),
}
flag := 0
defer tick.ticker.Stop()
for {
select {
case t := <-tick.ticker.C:
go somethingYouWantToDo(tick, &flag, t)
}
}
}
// output
// Current time: 2009-11-10 23:00:03 +0000 UTC m=+3.000000001
// Current time: 2009-11-10 23:00:06 +0000 UTC m=+6.000000001
// Current time: 2009-11-10 23:00:12 +0000 UTC m=+12.000000001
// Current time: 2009-11-10 23:00:15 +0000 UTC m=+15.000000001
// Current time: 2009-11-10 23:00:21 +0000 UTC m=+21.000000001
// Current time: 2009-11-10 23:00:24 +0000 UTC m=+24.000000001
// Current time: 2009-11-10 23:00:30 +0000 UTC m=+30.000000001
// Current time: 2009-11-10 23:00:33 +0000 UTC m=+33.000000001
// Current time: 2009-11-10 23:00:39 +0000 UTC m=+39.000000001
// Current time: 2009-11-10 23:00:42 +0000 UTC m=+42.000000001
// Current time: 2009-11-10 23:00:48 +0000 UTC m=+48.000000001
// Current time: 2009-11-10 23:00:51 +0000 UTC m=+51.000000001
// Current time: 2009-11-10 23:00:57 +0000 UTC m=+57.000000001
// Current time: 2009-11-10 23:01:00 +0000 UTC m=+60.000000001
// Current time: 2009-11-10 23:01:06 +0000 UTC m=+66.000000001
// Current time: 2009-11-10 23:01:09 +0000 UTC m=+69.000000001
我有一些功能必须定期 运行。我为此使用了自动收报机。但是如果ticker已经是运行ning了,时间间隔又过了,应该不会再执行了。
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(3*time.Second)
flag := 0
defer ticker.Stop()
for {
select {
case t := <-ticker.C:
flag = flag + 1
if (flag % 2 ==0 ) {
time.Sleep(time.Second*4)
}
fmt.Println("Current time: ", t)
}
}
}
https://play.golang.org/p/2xV2MYInn4I
在操场上,自动收报机每 3 秒打印一次,但自动收报机每均匀转动一次,作业花费的时间比间隔时间长。我希望它不会 运行 然后放弃那些滴答声。
我该怎么做?
行情通道已缓冲,这就是为什么您可能会一个接一个地看到多个触发器。您可以通过简单地将代码的值传输到无缓冲通道来防止这种情况(另请注意,从代码接收到的 time.Time 值不是当前时间,而是最后一个报价的时间):
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan time.Time) // unbuffered
ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop()
go func() {
for t := range ticker.C {
select {
case c <- t:
default:
}
}
}()
for flag := 0; flag < 8; flag++ {
<-c
if flag%2 == 0 {
time.Sleep(time.Second * 4)
}
fmt.Println("Current time: ", time.Now())
}
}
// Output:
// Current time: 2020-02-19 12:21:57.095433032 +0100 CET m=+3.000213350
// Current time: 2020-02-19 12:22:04.095585208 +0100 CET m=+10.000365520
// Current time: 2020-02-19 12:22:06.095363327 +0100 CET m=+12.000143680
// Current time: 2020-02-19 12:22:13.095605268 +0100 CET m=+19.000385598
// Current time: 2020-02-19 12:22:15.095371885 +0100 CET m=+21.000152174
// Current time: 2020-02-19 12:22:22.095537562 +0100 CET m=+28.000317857
// Current time: 2020-02-19 12:22:24.095431317 +0100 CET m=+30.000211625
// Current time: 2020-02-19 12:22:31.095524308 +0100 CET m=+37.000304595
在同一个 goroutine 中休眠只会延迟执行。 ticker 同时在一个单独的 goroutine 中运行。因此,即使您使用全局变量来维护执行状态 - 它也不会在睡眠时为您提供所需的结果。然而,将整个 "sleeping" 迁移到一个单独的 goroutine 中会产生:
package main
import (
"fmt"
"time"
)
type Tick struct {
ticker *time.Ticker
executing bool
}
func somethingYouWantToDo(tick *Tick, flag *int, t time.Time) {
if tick.executing {
return
}
tick.executing = true
*flag = *flag + 1
if (*flag % 2 ==0 ) {
time.Sleep(time.Second*4)
}
fmt.Println("Current time: ", t)
tick.executing = false
}
func main() {
tick := &Tick{
ticker: time.NewTicker(3*time.Second),
}
flag := 0
defer tick.ticker.Stop()
for {
select {
case t := <-tick.ticker.C:
go somethingYouWantToDo(tick, &flag, t)
}
}
}
// output
// Current time: 2009-11-10 23:00:03 +0000 UTC m=+3.000000001
// Current time: 2009-11-10 23:00:06 +0000 UTC m=+6.000000001
// Current time: 2009-11-10 23:00:12 +0000 UTC m=+12.000000001
// Current time: 2009-11-10 23:00:15 +0000 UTC m=+15.000000001
// Current time: 2009-11-10 23:00:21 +0000 UTC m=+21.000000001
// Current time: 2009-11-10 23:00:24 +0000 UTC m=+24.000000001
// Current time: 2009-11-10 23:00:30 +0000 UTC m=+30.000000001
// Current time: 2009-11-10 23:00:33 +0000 UTC m=+33.000000001
// Current time: 2009-11-10 23:00:39 +0000 UTC m=+39.000000001
// Current time: 2009-11-10 23:00:42 +0000 UTC m=+42.000000001
// Current time: 2009-11-10 23:00:48 +0000 UTC m=+48.000000001
// Current time: 2009-11-10 23:00:51 +0000 UTC m=+51.000000001
// Current time: 2009-11-10 23:00:57 +0000 UTC m=+57.000000001
// Current time: 2009-11-10 23:01:00 +0000 UTC m=+60.000000001
// Current time: 2009-11-10 23:01:06 +0000 UTC m=+66.000000001
// Current time: 2009-11-10 23:01:09 +0000 UTC m=+69.000000001