Golang:等待x个时间,然后再次循环,而不启动新的goroutine
我有一个循环,在再次循环之前需要等待一段随机的时间 我所拥有的:Golang:等待x个时间,然后再次循环,而不启动新的goroutine,go,time,Go,Time,我有一个循环,在再次循环之前需要等待一段随机的时间 我所拥有的: for { rand.Seed(time.Now().UnixNano()) r := rand.Int() //Do stuff t, _ := time.ParseDuration(string(r) + "ms") time.Sleep(t) } 不幸的是,循环运行多次,就像time.Sleep不工作一样。for循环不会产生新的goroutine,除非您在循环中显式地这样做。默认情况
for {
rand.Seed(time.Now().UnixNano())
r := rand.Int()
//Do stuff
t, _ := time.ParseDuration(string(r) + "ms")
time.Sleep(t)
}
不幸的是,循环运行多次,就像
time.Sleep
不工作一样。for
循环不会产生新的goroutine,除非您在循环中显式地这样做。默认情况下,下一个循环仅在上一个循环完成后开始。所以你不需要任何延迟。只需确保在您的周期中不要使用go
关键字
如果要启动goroutines:
for {
rand.Seed(time.Now().UnixNano())
r := rand.Int()
//Do stuff in separate goroutine
go DoStuff()
t, _ := time.ParseDuration(string(r) + "ms")
time.Sleep(t)
}
这样将启动新的goroutine。您应该检查当前从
t中丢弃的错误,:=time.ParseDuration
:您传递给睡眠的time.Duration
处于零值,这将导致函数睡眠0纳秒
更改#1:处理错误
导致:
时间:持续时间无效�ms
由于您直接将整数转换为字符串,因此会弄乱大量您并不真正想要的unicode逻辑
更改2:使用strconv:
结果:
时间:无效持续时间7936209096285811603ms
之所以出现此错误,是因为time.Duration
使用int64
表示存储纳秒的时间。您试图传递一个表示毫秒的int
:大部分时间都会溢出
更改#3:直接分配到持续时间
现在它工作了!我的函数生成的第一个整数是649508928394582529,我将其转换为time.Duration
(同样,这是纳秒的int64
)。
这大约是649508928秒:刚刚超过一周
看起来很多。但是请记住,您试图使用生成的int
作为毫秒:这是10^6倍
变化4:循环外的种子
当我们在做的时候,让我们擦亮一点:
rand.Seed(time.Now().UnixNano())
for {
r := rand.Int()
log.Println(r)
d := time.Duration(r)
time.Sleep(d)
}
说明:伪随机数生成器是一种状态机。你必须给它喂一粒种子,然后它就会永远工作。每次运行时给它一个不同的种子并不能改善它的随机性:它在一个可预测的值(时间)上反复应用相同的算法。通过直接使用
time.Now()Unix()
只对PRNG进行一次种子设定,您可以获得相同程度的随机性。剩下的我不明白,time.Sleep()
不会启动新的goroutine。好的。我的//Do stuff在第一次迭代中运行一次,在第二次迭代中运行两次,在第三次迭代中运行三次,依此类推……我如何使它每次只运行一次?它还将在0ms到292271 millenia(在64位系统上;在32位系统上最多24天)之间的随机时间内休眠,这看起来可能不是你想要的。引用的代码中没有任何东西会导致你描述的行为,但是没有太多可以继续的。你能提供一个能证明问题的答案吗?你是对的。在意识到这不是睡眠之后,我才明白。谢谢。如果用户需要整数为毫秒,我还将包括d:=time.Duration(r)*time.millis秒
。他可能会以某种方式限制它,或者随机部分可能只是为了这个问题。
t, err := time.ParseDuration(strconv.Itoa(r) + "ms")
if err != nil {
log.Println(err)
return
}
for {
rand.Seed(time.Now().UnixNano())
r := rand.Int()
log.Println(r)
d := time.Duration(r)
time.Sleep(d)
}
rand.Seed(time.Now().UnixNano())
for {
r := rand.Int()
log.Println(r)
d := time.Duration(r)
time.Sleep(d)
}