返回介绍

10.5.1.1 忘记解锁 mutex 的后果

发布于 2024-08-14 12:50:32 字数 3094 浏览 0 评论 0 收藏 0

这节,您会看到如果您忘记解锁 sync.Mutex 的后果。您将使用 forgetMutex.go 代码来做这个,把它分两部分来介绍。

forgetMutex.go 第一段代码如下:

package main

import (
    "fmt"
    "sync"
)

var m sync.Mutex

func function() {
    m.Lock()
    fmt.Println("Locked!")
}

这个程序的所有问题是由于开发者忘记释放 m sync.Mutex 互斥体的锁导致的。然而,如果您的程序只调用 function() 一次,那一切正常!

forgetMutex.go 的第二段如下:

func main() {
    var w sync.WaitGroup

    go func() {
        defer w.Done()
        function()
    }()
    w.Add(1)

    go func() {
        defer w.Done()
        function()
    }()
    w.Add(1)

    w.Wait()
}

main() 函数没有任何问题,它创建两个 goroutines 并等它们完成。

执行 forgetMutex.go 产生如下输出:

$go run forgetMutex.go
Locked!
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001209c)
    /usr/local/Cellar/go/1.9.4/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420012090)
    /usr/local/Cellar/go/1.9.4/libexec/src/sync/waitgroup.go:131 +0x72 main.main()
    /Users/mtsouk/forgetMutex.go:30 +0xb6

goroutine 5 [semacquire]:
sync.runtime_SemacquireMutex(0x115c6fc, 0x0)
    /usr/local/Cellar/go/1.9.4/libexec/src/runtime/sema.go:71 +0x3d
sync.(*Mutex).Lock(0x115c6f8)
    /usr/local/Cellar/go/1.9.4/libexec/src/sync/mutex.go:134 +0xee main.function()
    /Users/mtsouk/forgetMutex.go:11 +0x2d main.main.func1(0xc420012090)
    /Users/mtsouk/forgetMutex.go:20 +0x48 created by main.main
    /Users/mtsouk/forgetMutex.go:18 +0x58 exit status 2

所以,忘记解锁 sync.Mutex 互斥体会产生崩溃即使是最简单的程序。这同样适用于您将在下一节中使用的 sync.RWMutex 类型的互斥锁。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文