是否需要同步?

时间:2015-08-12 10:51:18

标签: go goroutine

我在对象

中定义了一个变量(r.something)
func (r *Runner) init() {
  r.something = make(map[string]int)
  r.something["a"]=1

  go r.goroutine()
}

而r.goroutine使用存储在r.something中的值而没有同步。 除了r.goroutine()

之外,没有其他人会读/写这个值

没有同步可以安全吗?

换句话说:我想在 goroutine start之前重新使用其他地方初始化的goroutine中的一些变量。这样安全吗?

其他问题: 在r.goroutine()完成之后,我希望能够使用来自其他地方的r.something(没有与其他goroutine的读/写重叠)。它也安全吗?

3 个答案:

答案 0 :(得分:5)

当然这是安全的,否则Go中的编程可能是一场噩梦(或者至少不那么令人愉快)。 The Go Memory Model是一篇有趣的内容。

例程创建是一个同步点。有一个与你非常相似的例子:

{{1}}

以下评论:

  

打电话给你好会打印"你好,世界"在未来的某个时刻(也许在你好回来之后)。

这是因为:

  

启动新goroutine的go语句在goroutine的执行开始之前发生

之前的这个词在这里至关重要,因为它意味着例程创建(在一个线程中)必须与其开始同步(可能在其他线程中),因此写入 a 必须通过新例程可见。

答案 1 :(得分:3)

如果没有这种变量可能出现不同的例程读取和写入操作的重叠的情况,那么你是对的:没有必要任何同步。

正如你所提到的那样,变量在之前初始化你的常规例程开始,你实际上是安全的。

答案 2 :(得分:1)

是的,这是安全的。根据{{​​3}}:

  • 启动新goroutine的go语句发生在goroutine的执行开始之前
  • 在单个goroutine中,before-before顺序是程序表达的顺序

这意味着在启动goroutine之前对变量所做的所有更改都在此goroutine中可见。

回答你的其他问题:这取决于你。通常,如果r.goroutine()已修改r.something并且您想要从其他goroutine中读取它,则需要使用同步。