美文网首页
gobyexample-mutexes

gobyexample-mutexes

作者: bocsoft | 来源:发表于2018-11-07 13:54 被阅读0次

来源:https://github.com/xg-wang/gobyexample/tree/master/examples

//使用一个_[互斥锁]_在Go协程间安全的访问数据
package main

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

func main() {
    var state = make(map[int]int)

    //同步对`state`的访问
    var mutex = &sync.Mutex{}

    //记录操作次数
    var ops int64 = 0

    //运行100个Go协程来重复读取state
    for r := 0; r < 100; r++ {
        go func() {
            total := 0
            for {
                key := rand.Intn(5)

                //确保对`state` 的独占访问
                mutex.Lock()
                total += state[key]
                mutex.Unlock()

                atomic.AddInt64(&ops, 1)

                //为了确保这个GO协程不会在调度中饿死,我们在每次操作后明确的使用
                //`runtime.Gosched()`进行释放。这个释放一般是自动处理的,像例如
                //每个通道操作后 或者`time.Sleep`的阻塞调用后相似。在此,我们需要手动处理
                runtime.Gosched()
            }
        }()
    }

    //运行10个协程模拟写入操作
    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.AddInt64(&ops, 1)

                runtime.Gosched()
            }
        }()
    }

    //让上述操作运行2秒
    time.Sleep(2 * time.Second)

    //获取并输出最终的操作计数
    opsFinal := atomic.LoadInt64(&ops)
    fmt.Println("ops:", opsFinal)

    //对`state`使用一个最终的锁,显示它是如何结束的
    mutex.Lock()
    fmt.Println("state:", state)
    mutex.Unlock()
}

输出结果:

ops: 8126595
state: map[4:72 0:43 3:33 2:49 1:22]

相关文章

网友评论

      本文标题:gobyexample-mutexes

      本文链接:https://www.haomeiwen.com/subject/ykqvxqtx.html