Go基础 专题
专题目录
您的位置:go > Go基础 专题 > Go互斥体实例
Go互斥体实例
作者:--    发布时间:2019-11-20

在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器状态。对于更复杂的状态,可以使用互斥体来安全地访问多个goroutine中的数据。

在这个例子中,状态(state)是一个映射。
示例中的互斥将同步访问状态。

我们将跟踪执行的读写操作的数量。

这里将启动100goroutine来对状态执行重复读取,每个goroutine中每毫秒读取一次。

对于每个读取,我们选择一个键来访问,lock()互斥体以确保对状态的独占访问,读取所选键的值,unlock()互斥体,并增加readops计数。

我们还将启动10goroutine来模拟写入,使用与读取相同的模式。

10goroutine在状态和互斥体上工作一秒钟。采集和报告最终操作计数。

收集和报告最终操作计数。用最后的锁状态,显示它是如何结束的。

运行程序显示,我们对互斥同步状态执行了大约90,000次的操作。

所有的示例代码,都放在 f:\worksp\golang 目录下。安装go编程环境请参考:http://www.h3.com/go/go_environment.html

mutexes.go的完整代码如下所示 -

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "sync/atomic"
    "time"
)

func main() {

    // for our example the `state` will be a map.
    var state = make(map[int]int)

    // this `mutex` will synchronize access to `state`.
    var mutex = &sync.mutex{}

    // we'll keep track of how many read and write
    // operations we do.
    var readops uint64 = 0
    var writeops uint64 = 0

    // here we start 100 goroutines to execute repeated
    // reads against the state, once per millisecond in
    // each goroutine.
    for r := 0; r < 100; r++ {
        go func() {
            total := 0
            for {

                // for each read we pick a key to access,
                // `lock()` the `mutex` to ensure
                // exclusive access to the `state`, read
                // the value at the chosen key,
                // `unlock()` the mutex, and increment
                // the `readops` count.
                key := rand.intn(5)
                mutex.lock()
                total += state[key]
                mutex.unlock()
                atomic.adduint64(&readops, 1)

                // wait a bit between reads.
                time.sleep(time.millisecond)
            }
        }()
    }

    // we'll also start 10 goroutines to simulate writes,
    // using the same pattern we did for reads.
    for w := 0; w < 10; w++ {
        go func() {
            for {
                key := rand.intn(5)
                val := rand.intn(100)
                mutex.lock()
                state[key] = val
                mutex.unlock()
                atomic.adduint64(&writeops, 1)
                time.sleep(time.millisecond)
            }
        }()
    }

    // let the 10 goroutines work on the `state` and
    // `mutex` for a second.
    time.sleep(time.second)

    // take and report final operation counts.
    readopsfinal := atomic.loaduint64(&readops)
    fmt.println("readops:", readopsfinal)
    writeopsfinal := atomic.loaduint64(&writeops)
    fmt.println("writeops:", writeopsfinal)

    // with a final lock of `state`, show how it ended up.
    mutex.lock()
    fmt.println("state:", state)
    mutex.unlock()
}

执行上面代码,将得到以下输出结果 -

f:\worksp\golang>go run mutexes.go
readops: 84546
writeops: 8473
state: map[0:99 3:3 4:62 1:18 2:89]

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册