Golang的time.Sleep存在bug吗?

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

golang time.Sleep bug?

问题

我为您翻译了以下内容:

我在下面编写了一个测试代码(gotest.go):

package main

import (
	"fmt"
	"time"
	"sync"
)        

func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	go testa()    

	wg.Wait()
}

func testa() {
	for {
		fmt.Println("test goroutine")
		time.Sleep(2 * time.Second)
	}
}

控制台输出:

go run gotest.go

然后,更改我的计算机日期(例如:2015-07-30 -> 2015-07-29)

然后,打印不会出现!!

这是一个 bug 吗?

(设置为下一天后可以正常工作)

我使用的是最新版本的 MacOs。

谢谢。

英文:

I make test code below(gotest.go)

package main

import (
	"fmt"
	"time"
	"sync"
)        

func main() {
	var wg sync.WaitGroup
	wg.Add(1)
	go testa()    

	wg.Wait()
}

func testa() {
	for {
		fmt.Println("test goroutine")
		time.Sleep(2 * time.Second)
	}
}

console

go run gotest.go

and, change my computer's date
(ex : 2015-07-30 -> 2015-07-29)

and then,
println not printed!!

is it bug??

(It is working to set next day)

I use MacOs latest ver.
Thank you.

答案1

得分: 15

在内部,睡眠是使用绝对时间来完成的:如果你在时间T调用Sleep(n),程序被安排在时间T + n唤醒,而不是在经过n时间后唤醒。

这通常是可取的,因为:

  • 时间通常不会倒流
  • 由于操作系统调度延迟,一个重复睡眠的程序可能会无限期地滞后于计划;使用绝对时间可以通过缩短睡眠间隔来补偿延迟。

在你的情况下,你只需要等待一天,程序就会重新开始打印。 Golang的time.Sleep存在bug吗?

或者将时间设置为稍微过去一点(比如15秒),然后在过去15秒加2秒后,观察程序是否恢复。

附注:为了阐明发生了什么,举个例子:

在2016-08-25 16:27:12,程序调用time.Sleep(2 * time.Second)
Go运行时安排该goroutine在2016-08-25 16:27:14唤醒,并将该goroutine置于睡眠状态。

与此同时...

用户将系统时间设置为2016-08-24 16:27:13。

现在,超时被安排在一天零一秒后到期。

这在使用POSIX CLOCK_MONOTONIC或等效机制的系统上不会发生。

英文:

Internally sleep is done with absolute time: if you call Sleep(n) at time T the program is scheduled not to wake up after n time, but at time T + n.

This is generally preferable because:

  • time usually does not flow backwards

  • due to OS scheduling delays a program which repeatedly sleeps may lag behind schedule indefinitely; using absolute time make it compensate for delays by sleeping for shorter intervals.

In your case, you just have to wait for a day for the program to start printing again. Golang的time.Sleep存在bug吗?

Or set a time just a little in the past (say 15 sec), and see the program resuming after 15+2 sec.

PS. To clarify what happens with an example:

At 2016-08-25 16:27:12 the program calls time.Sleep(2 * time.Second)
The Go runtime schedules the goroutine to be woken up on 2016-08-25 at 16:27:14 and puts the goroutine to sleep

meanwhile ...

the user sets the system time to 2016-08-24 16:27:13

now the timeout is scheduled to expire one day and one second later.

This should not happen on systems, on which Go uses POSIX CLOCK_MONOTONIC or equivalent thereof.

答案2

得分: 3

time.Sleep(20_000_000_000) n 是纳秒单位

英文:

time.Sleep(20_000_000_000) n is nanoseconds

huangapple
  • 本文由 发表于 2015年7月31日 16:06:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/31741172.html
匿名

发表评论

匿名网友

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

确定