Mutex 似乎没有正确锁定
Mutex does not seem to be locking properly
我刚开始学习互斥。我认为下面的程序 return 总共 1000,但我得到的结果各不相同,所以我认为我做错了什么...
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add() {
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
for x := 1; x <= 10; x++ {
go add()
}
fmt.Printf("Total is %v\n", total)
}
在检查结果之前,您不会等待您开始的任何 goroutine 完成。使用 WaitGroup
等待所有这些完成。
您有一场数据竞赛。因此,结果未定义。
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add() {
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
for x := 1; x <= 10; x++ {
go add()
}
fmt.Printf("Total is %v\n", total)
}
输出:
$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x0000005ba408 by main goroutine:
runtime.convT2E64()
/home/peter/go/src/runtime/iface.go:335 +0x0
main.main()
/home/peter/src/racer.go:23 +0x84
Previous write at 0x0000005ba408 by goroutine 14:
main.add()
/home/peter/src/racer.go:14 +0x76
Goroutine 14 (running) created at:
main.main()
/home/peter/src/racer.go:21 +0x52
==================
Total is 960
Found 1 data race(s)
exit status 66
$
主函数returns在gorutines完成它们的工作之前,你应该添加sync.WaitGroup
,这段代码如你所愿:https://play.golang.com/p/_OfrZae0soB
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add(wg *sync.WaitGroup) {
defer wg.Done()
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
var wg sync.WaitGroup
for x := 1; x <= 10; x++ {
wg.Add(1)
go add(&wg)
}
wg.Wait()
fmt.Printf("Total is %v\n", total)
}
我刚开始学习互斥。我认为下面的程序 return 总共 1000,但我得到的结果各不相同,所以我认为我做错了什么...
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add() {
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
for x := 1; x <= 10; x++ {
go add()
}
fmt.Printf("Total is %v\n", total)
}
在检查结果之前,您不会等待您开始的任何 goroutine 完成。使用 WaitGroup
等待所有这些完成。
您有一场数据竞赛。因此,结果未定义。
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add() {
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
for x := 1; x <= 10; x++ {
go add()
}
fmt.Printf("Total is %v\n", total)
}
输出:
$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x0000005ba408 by main goroutine:
runtime.convT2E64()
/home/peter/go/src/runtime/iface.go:335 +0x0
main.main()
/home/peter/src/racer.go:23 +0x84
Previous write at 0x0000005ba408 by goroutine 14:
main.add()
/home/peter/src/racer.go:14 +0x76
Goroutine 14 (running) created at:
main.main()
/home/peter/src/racer.go:21 +0x52
==================
Total is 960
Found 1 data race(s)
exit status 66
$
主函数returns在gorutines完成它们的工作之前,你应该添加sync.WaitGroup
,这段代码如你所愿:https://play.golang.com/p/_OfrZae0soB
package main
import (
"fmt"
"sync"
)
var total int
var locker sync.RWMutex
func add(wg *sync.WaitGroup) {
defer wg.Done()
for x := 1; x <= 100; x++ {
locker.Lock()
total += 1
locker.Unlock()
}
}
func main() {
var wg sync.WaitGroup
for x := 1; x <= 10; x++ {
wg.Add(1)
go add(&wg)
}
wg.Wait()
fmt.Printf("Total is %v\n", total)
}