Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
103 lines (77 sloc) 2.34 KB

sync.Mutex 类型

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 同时去修改共享变量,这也是随机输出的主要原因。

You can’t perform that action at this time.