英文:
Initializing a RWMutex crashes in golang?
问题
以下代码出现了以下错误,为什么??
package main
import (
"sync"
)
var foo *sync.RWMutex
func main() {
foo.Lock()
}
输出:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0x8125c]
goroutine 1 [running]:
sync.(*RWMutex).Lock(0x0, 0x104000f0)
/usr/local/go/src/sync/rwmutex.go:86 +0x1c
main.main()
/tmp/sandbox093456788/main.go:11 +0x20
Program exited.
当你使用以下任一行对 foo
变量进行初始化时,就不会发生这种情况:
var foo = new(sync.RWMutex)
var foo sync.RWMutex
英文:
The following code crashes with the following error, why??
package main
import (
"sync"
)
var foo *sync.RWMutex
func main() {
foo.Lock()
}
outputs:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0x8125c]
goroutine 1 [running]:
sync.(*RWMutex).Lock(0x0, 0x104000f0)
/usr/local/go/src/sync/rwmutex.go:86 +0x1c
main.main()
/tmp/sandbox093456788/main.go:11 +0x20
Program exited.
it will not happen, when you use one of the following lines
var foo = new(sync.RWMutex)
var foo sync.RWMutex
for the initialization of the foo variable.
答案1
得分: 5
互斥锁通常设计为无需任何类型的初始化。也就是说,只需要一个值为零的互斥锁即可使用它们。要修复你的程序,将foo
声明为一个值,而不是一个互斥锁的指针:
var foo sync.RWMutex
func main() {
foo.Lock()
}
当你将foo
声明为一个指针时:
var foo *sync.RWMutex
foo
是一个值为零的指针(指向sync.RWMutex
类型),也就是说它并没有指向有效的互斥锁值。foo
是nil
。这就是为什么在调用方法时会出现空指针异常。
然而,请注意,在协程/函数之间共享互斥锁时,你需要在初始化后将它们作为指针传递,否则它们将无法共享。
根据文档:
在首次使用后,不得复制RWMutex。
文档链接:https://golang.org/pkg/sync/#RWMutex
英文:
The mutexes are generally designed to work without any type of initialization. That is, a zero valued mutex is all you need to use them. To fix your program, declare foo
as a value. Not a pointer to a mutex:
var foo sync.RWMutex
func main() {
foo.Lock()
}
When you declare foo
as a pointer:
var foo *sync.RWMutex
foo
is a zero valued pointer (to type sync.RWMutex
), i.e. it does not point to a valid mutex value. foo
is nil
. That's why you get the nil pointer exception when calling a method.
However, note that to share the mutex between goroutines/functions, you're going to have to pass them as pointers, after they have been initialized (like above), or they'll not be shared.
From the docs:
> An RWMutex must not be copied after first use.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论