是否需要同步?
Is synchronization required?
我在对象中定义了一个变量 (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()
之外,没有其他人会 read/write 这个值
不同步是否安全?
换句话说:我想重用在在 goroutine 启动之前在其他地方初始化的goroutine 中的一些变量。安全吗?
附加问题:
r.goroutine() 完成后,我希望能够从其他地方使用 r.something(没有 read/write 与其他 goroutines 重叠)。也安全吗?
如果不存在不同go-routines对读写操作的重叠的情况,那么你是对的:不需要任何同步。
正如您所提到的,在您的 go-routine 开始之前初始化了变量,您实际上是安全的。
是的,很安全。根据Go Memory Model:
- 启动新 goroutine 的 go 语句发生在 goroutine 开始执行之前
- 在单个goroutine中,happens-before顺序就是程序表达的顺序
这意味着您在启动 goroutine 之前对变量所做的所有更改都在此 goroutine 中可见。
回答您的附加问题:视情况而定。通常如果 r.goroutine()
修改了 r.something
并且你想从另一个 goroutine 读取它你需要使用同步。
当然这是安全的,否则用 Go 编程可能是一场噩梦(或者至少不那么愉快)。 The Go Memory Model 是一篇有趣的文章。
例程创建是一个同步点。有一个例子与你的非常相似:
var a string
func f() {
print(a)
}
func hello() {
a = "hello, world"
go f()
}
评论如下:
calling hello will print "hello, world" at some point in the future (perhaps after hello has returned).
这是因为:
The go statement that starts a new goroutine happens before the goroutine's execution begins.
单词 before 在这里很重要,因为它意味着例程创建(在一个线程中)必须与其开始同步(可能在其他线程中),因此写入 a 必须对新例程可见。
我在对象中定义了一个变量 (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()
之外,没有其他人会 read/write 这个值不同步是否安全?
换句话说:我想重用在在 goroutine 启动之前在其他地方初始化的goroutine 中的一些变量。安全吗?
附加问题: r.goroutine() 完成后,我希望能够从其他地方使用 r.something(没有 read/write 与其他 goroutines 重叠)。也安全吗?
如果不存在不同go-routines对读写操作的重叠的情况,那么你是对的:不需要任何同步。
正如您所提到的,在您的 go-routine 开始之前初始化了变量,您实际上是安全的。
是的,很安全。根据Go Memory Model:
- 启动新 goroutine 的 go 语句发生在 goroutine 开始执行之前
- 在单个goroutine中,happens-before顺序就是程序表达的顺序
这意味着您在启动 goroutine 之前对变量所做的所有更改都在此 goroutine 中可见。
回答您的附加问题:视情况而定。通常如果 r.goroutine()
修改了 r.something
并且你想从另一个 goroutine 读取它你需要使用同步。
当然这是安全的,否则用 Go 编程可能是一场噩梦(或者至少不那么愉快)。 The Go Memory Model 是一篇有趣的文章。
例程创建是一个同步点。有一个例子与你的非常相似:
var a string
func f() {
print(a)
}
func hello() {
a = "hello, world"
go f()
}
评论如下:
calling hello will print "hello, world" at some point in the future (perhaps after hello has returned).
这是因为:
The go statement that starts a new goroutine happens before the goroutine's execution begins.
单词 before 在这里很重要,因为它意味着例程创建(在一个线程中)必须与其开始同步(可能在其他线程中),因此写入 a 必须对新例程可见。