如何每秒重复执行函数N次?

huangapple go评论76阅读模式
英文:

How to repeat the function N times per second?

问题

在Go语言中,如何每秒重复执行函数N次?

你可以这样做:

N := 30 //每秒重复30次
for {
    //执行某些操作
    time.Sleep(time.Second / time.Duration(N))
}

这样做会使得每次重复之间的时间间隔保持一致。

英文:

How to repeat the function N times per second in Go?

I can:

N := 30 //Repeat 30 times per second
for {
	//Do something
	time.Sleep(time.Second * time.Duration(N))
}

But that just makes the intervals between repetitions

答案1

得分: 5

有两个选项,都不能保证每秒执行 x 次。

选项一:

将 N 设置为 1/30,这样 sleep 将持续 1/30 秒。

N := 30 //每秒重复 30 次
for {
    //做一些事情
    time.Sleep(time.Duration(1e9 / N))  //time.second 常量不必要(参见 kostya 的评论)
}

选项二:

将 N 设置为 1,即一秒的睡眠时间。

N := 1  //一秒的睡眠时间
for {
    for i := 1; i <= 30; i++ {
        //做一些事情
    }
    time.Sleep(time.Second * time.Duration(N))
}

请注意,在选项二中,所有事情都会一次性发生,然后等待一秒钟。第一个选项将在整个秒钟内分散执行某些操作。由于计算机的时间问题,这不会是精确的:sleep 不能保证它会在你期望的时间精确唤醒。

英文:

There are two options, neither will get you a guaranteed x times per second.

  • Set N not to 30 but 1/30. Thus the sleep will be for 1/30th of a second.
  • Have an internal for-loop that loops 30 times and executes your 'do something', and then on exit you hit the statement that sleeps for a second.

Option One:

N := 30 //Repeat 30 times per second
for {
    //Do something
    time.Sleep(time.Duration(1e9 / N))  //time.second constant unnecessary (see kostya comments)
}

Option Two:

N := 1  //Sleep duration of one second
for {
    for i := 1;  i&lt;=30; i++ {
        //Do something
    }
    time.Sleep(time.Second * time.Duration(N))
}

Note that in option two, everything happens all at once, and then you wait a second. The first option will space out the do something across the second. Because of timing in computers this won't be precise: sleep cannot guarantee it will wake up precisely when you expect.

答案2

得分: 5

你可以使用time.Ticker来处理所有的簿记工作。唯一的“问题”是,如果你的操作花费的时间超过预期,你将会丢失一些滴答声(因此每秒运行的次数会少于N)。

func doSomething() {
    const N = 30
    ticker := time.NewTicker(time.Second / N)
    for range ticker.C {
        fmt.Println("做任何不超过1/N秒的事情")
    }
}

https://play.golang.org/p/Gq-tWMvxIk

英文:

You can use a time.Ticker to handle all the book-keeping for you. The only "issue" is that if your operation takes longer than expected you'll loose ticks (and thus run fewer than N per second).

func doSomething() {
	const N = 30
	ticker := time.NewTicker(time.Second / N)
	for range ticker.C {
		fmt.Println(&quot;Do anything that takes no longer than 1/Nth of a second&quot;)
	}
}

https://play.golang.org/p/Gq-tWMvxIk

huangapple
  • 本文由 发表于 2015年7月10日 00:23:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/31323118.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定