在 goroutine 中使用指针接收器
Using a pointer receiver in a goroutine
我有一个带有指针接收器的方法,我想知道在这个方法的 goroutine 中使用这个指针接收器是否安全?或者我应该将这个指针接收器作为参数传递?
例如:
func (m *dummyStruct) doSomething {
/* do a bunch of stuff */
go func() {
m.a = x
m.doSomethingElse()
}()
return y
}
我知道将 m 作为参数传递给 goroutine 不会出错,但我想知道这是否非常必要
如果要修改 m
的状态,则需要互斥锁和谨慎的锁定模式。
除此之外,在大多数情况下,这会增加跨线程边界的上下文切换。
这就是我们拥有 Go 习语的原因:
Do not communicate by sharing memory;
instead, share memory by communicating.
我看过 link @eduncan911 的帖子,但从未尝试应用它。希望此示例对您有所帮助:
package main
import (
"fmt"
"time"
)
type dummyStruct struct {
a int
}
func (m *dummyStruct) doSomethingElse() {
fmt.Println(m.a)
}
func doSomething(c chan int) {
for i := 0; i < 5; i++ {
go func() {
x := time.Now().Unix()
c <- int(x)
}()
time.Sleep(time.Second)
}
}
func main() {
outputs := make(chan int)
m := &dummyStruct{}
doSomething(outputs)
for {
//block until we can read from channel:
x := <-outputs
m.a = x
m.doSomethingElse()
}
}
//Output:
go run main.go
1474052448
1474052449
1474052450
1474052451
1474052452
fatal error: all goroutines are asleep - deadlock!
我认为指针不是共享 goroutines 数据的正确方式,因为它会降低性能。最好的选择是频道。
我有一个带有指针接收器的方法,我想知道在这个方法的 goroutine 中使用这个指针接收器是否安全?或者我应该将这个指针接收器作为参数传递?
例如:
func (m *dummyStruct) doSomething {
/* do a bunch of stuff */
go func() {
m.a = x
m.doSomethingElse()
}()
return y
}
我知道将 m 作为参数传递给 goroutine 不会出错,但我想知道这是否非常必要
如果要修改 m
的状态,则需要互斥锁和谨慎的锁定模式。
除此之外,在大多数情况下,这会增加跨线程边界的上下文切换。
这就是我们拥有 Go 习语的原因:
Do not communicate by sharing memory; instead, share memory by communicating.
我看过 link @eduncan911 的帖子,但从未尝试应用它。希望此示例对您有所帮助:
package main
import (
"fmt"
"time"
)
type dummyStruct struct {
a int
}
func (m *dummyStruct) doSomethingElse() {
fmt.Println(m.a)
}
func doSomething(c chan int) {
for i := 0; i < 5; i++ {
go func() {
x := time.Now().Unix()
c <- int(x)
}()
time.Sleep(time.Second)
}
}
func main() {
outputs := make(chan int)
m := &dummyStruct{}
doSomething(outputs)
for {
//block until we can read from channel:
x := <-outputs
m.a = x
m.doSomethingElse()
}
}
//Output:
go run main.go
1474052448
1474052449
1474052450
1474052451
1474052452
fatal error: all goroutines are asleep - deadlock!
我认为指针不是共享 goroutines 数据的正确方式,因为它会降低性能。最好的选择是频道。