返回介绍

10.5.1 sync.Mutex 类型

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

sync.Mutex 类型是 Go 实现的一个互斥体。它的定义可以在 sync 目录的 mutex.go 文件中找到,内容如下:

""

sync.Mutex 类型的定义没有什么特别的。所有的工作都是由 sync.Lock()sync.Unlock() 来做的,它们分别能加锁和解锁 sync.Mutex 互斥体。给互斥体上锁意味着没人可以操作它,直到使用 sync.Unlock() 函数解锁。

mutex.go 程序分为五部分介绍,来说明 sync.Mutex 类型的使用。

mutex.go 的第一段代码如下:

package main

import (
    "fmt"
    "os"
    "strconv"
    "sync"
    "time"
)

var (
    m sync.Mutex
    v1 int
)

mutex.go 的第二段代码如下:

func change(i int) {
    m.Lock()
    time.Sleep(time.Second)
    v1 = v1 + 1
    if v1 % 10 == 0 {
        v1 = v1 - 10*i
    }
    m.Unlock()
}

这个函数的关键部分是 m.Lock()m.Unlock() 之间的代码。

mutex.go 的第三部分如下:

func read() int {
    m.Lock()
    a := v1
    m.Unlock()
    return a
}

同样,这个函数的关键部分也由 m.Lock()m.Unlock() 表达式限定。

mutex.go 的第四部分代码如下:

func main() {
    if len(os.Args) != 2 {
        fmt.Println("Please give me an integer!")
        return
    }

    numGR, err := strconv.Atoi(os.Args[1])
    if err != nil {
        fmt.Println(err)
        return
    }
    var waitGroup sync.WaitGroup

mutex.go 的最后一段代码如下:

    fmt.Printf("%d ", read())
    for i := 0; i < numGR; i++ {
        waitGroup.Add(1)
        go func(i int) {
            defer waitGroup.Done()
            change(i)
            fmt.Printf("-> %d", read())
        }(i)
    }

    waitGroup.Wait()
    fmt.Printf("-> %d\n", read())
}

执行 mutex.go 将产生如下输出:

""

如果您从 change() 函数移除 m.Lock()m.Unlock() 表达式,这个程序会产生类似如下输出:

""

输出中发生改变的原因是所有 goroutines 同时去修改共享变量,这也是随机输出的主要原因。

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

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

发布评论

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