在Golang中初始化RWMutex会导致崩溃吗?

huangapple go评论62阅读模式
英文:

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类型),也就是说它并没有指向有效的互斥锁值。foonil。这就是为什么在调用方法时会出现空指针异常。

然而,请注意,在协程/函数之间共享互斥锁时,你需要在初始化后将它们作为指针传递,否则它们将无法共享。

根据文档:

在首次使用后,不得复制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.

Docs: https://golang.org/pkg/sync/#RWMutex

huangapple
  • 本文由 发表于 2017年5月27日 18:36:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/44215799.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定