关于 golang 互斥锁的一个疑问

2019-07-08 13:20:29 +08:00
 gramyang

代码见 https://github.com/GramYang/GoTest/blob/master/sync/mutex1.go

第一个 test 输出的是小于 1000 的随机值。 第二个 test 稳定输出 1000,但是限制了原生线程的数量,这在工作环境中显然是不可能的。 第三个 test 稳定输出 1000,方法和我之前用过的 currenthashmap 的用法一样。这里已经去掉了互斥锁。

那么问题来了:既然互斥锁锁的只是 goroutine,而多个原生线程并发仍然会产生并发错误,那么到底该怎么正确使用互斥锁呢?

3043 次点击
所在节点    Go 编程语言
6 条回复
Maboroshii
2019-07-08 13:47:54 +08:00
下面是 go playground 的输出。
func passes lock by value: sync.Mutex
这一句, 锁不能用值传递, 改成全局变量或者放在结构体里面再试。


./prog.go:38:8: call of func(i int, m sync.Mutex) {
fmt.Println("Not lock: ", i)
mutex.Lock()
fmt.Println("Lock: ", i)
time.Sleep(time.Second)
fmt.Println("Unlock: ", i)
mutex.Unlock()
defer wait.Done()
} copies lock value: sync.Mutex
./prog.go:30:20: func passes lock by value: sync.Mutex
./prog.go:58:8: call of func(c *counter, m sync.Mutex) {
m.Lock()
defer m.Unlock()
c.value++
wg.Done()
} copies lock value: sync.Mutex
./prog.go:53:25: func passes lock by value: sync.Mutex
Go vet exited.

数数:1000

play.go
gramyang
2019-07-08 13:51:25 +08:00
@Maboroshii 不行
gramyang
2019-07-08 14:00:00 +08:00
@Maboroshii 把锁换成指针传递后可以了。。。。。
Maboroshii
2019-07-08 14:01:23 +08:00
@gramyang #2

type counter struct {
sync.Mutex
value int
}

func test2() {
runtime.GOMAXPROCS(1)
var wg sync.WaitGroup
wg.Add(1000)
c := new(counter)
c.value=0
for i := 0; i < 1000; i++ {
go func(c *counter) {
c.Lock()
defer c.Unlock()
c.value++
wg.Done()
}(c)
}
wg.Wait()
fmt.Println("数数:", c.value)
}

func main() {
test2()
}
xeaglex
2019-07-08 17:18:14 +08:00
[官方文档]( https://godoc.org/sync) 第一段话说了:

> Values containing the types defined in this package should not be copied.
pubby
2019-07-08 18:06:24 +08:00
想起了以前偷懒这样写

client := &http.Client{}
t := *( http.DefaultTransport.(*http.Transport))
t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client.Transport = http.RoundTripper(&t)

结果高并发时 http 内部锁随机炸

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/580971

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX