我正在通过编写一个简单的程序来学习 Go,该程序同时从几个 http 服务器下载传感器数据文件。服务器上的传感器数据文件会定期刷新(30 秒或 2 分钟,取决于“来源”)。下载数据可能需要 100 毫秒到 10 秒的时间。所以我阅读了每个服务器(OriginContext)的一些配置。然后我为每个 OriginContext 启动一个控制器。每个控制器持续触发一个执行下载等操作的 goroutine。
我将我的代码精简为一个最小的例子,以某种方式/希望仍然显示我的意图。当我运行它时,会有两个控制器,但不知何故,当它们触发 doStuffThatMayTakeLongTime() 方法时,它们都引用了相同的配置。
那么,我是如何在这里混淆 goroutines 中变量和指针的作用域的呢?
我对 Go 很陌生,这也是我第一次尝试使用使用指针的语言。嗯,我害羞的 C/C++ 尝试是在十多年前......所以我认为我的困惑在于引用/值/取消引用,但我看不到它。
这是代码:
package main
import (
"log"
"time"
)
type OriginContext struct {
Origin string
Offset time.Duration
Interval time.Duration
}
type Controller struct {
originContext *OriginContext
}
func NewController(originContext *OriginContext) (w *Controller) {
log.Printf("Controller starting loop for origin %s.", originContext.Origin)
w = &Controller{originContext}
w.start()
return w
}
func (w *Controller) start() {
log.Println("start() of", w.originContext.Origin)
go func() {
time.Sleep(w.originContext.Offset)
ticker := time.NewTicker(w.originContext.Interval)
go w.doStuffThatMayTakeLongTime() // iteration zero
for {
select {
case <-ticker.C:
go w.doStuffThatMayTakeLongTime()
}
}
}()
}
func (w *Controller) doStuffThatMayTakeLongTime() {
log.Printf("%s doing stuff", w.originContext.Origin)
}
这是一些输出:
2015/09/07 14:30:11 Starting Controller alpha.
2015/09/07 14:30:11 Controller starting loop for origin alpha.
2015/09/07 14:30:11 start() of alpha
2015/09/07 14:30:11 Starting Controller bravo.
2015/09/07 14:30:11 Controller starting loop for origin bravo.
2015/09/07 14:30:11 start() of bravo
2015/09/07 14:30:16 bravo doing stuff
2015/09/07 14:30:16 bravo doing stuff
2015/09/07 14:30:26 bravo doing stuff
2015/09/07 14:30:26 bravo doing stuff
应该有 alpha 和 bravo做事,但只有 bravo。
12345678_0001
相关分类