zoukankan      html  css  js  c++  java
  • go语言从例子开始之Example36.互斥锁

    在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器。对于更加复杂的情况,我们可以使用一个互斥锁来在 Go 协程间安全的访问数据。

    Example:

    package main
    import (
        "fmt"
        "math/rand"
        "runtime"
        "sync"
        "sync/atomic"
        "time"
    )
    func main() {
      //在我们的例子中,state 是一个 map。
    
        var state = make(map[int]int)
      //这里的 mutex 将同步对 state 的访问。
    
        var mutex = &sync.Mutex{}
    we'll see later, ops will count how manyoperations we perform against the state.为了比较基于互斥锁的处理方式和我们后面将要看到的其他方式,ops 将记录我们对 state 的操作次数。
    
        var ops int64 = 0
      //这里我们运行 100 个 Go 协程来重复读取 state。
    
        for r := 0; r < 100; r++ {
            go func() {
                total := 0
                for {
              //每次循环读取,我们使用一个键来进行访问,Lock() 这个 mutex 来确保对 state 的独占访问,读取选定的键的值,Unlock() 这个mutex,并且 ops 值加 1。
    
                    key := rand.Intn(5)
                    mutex.Lock()
                    total += state[key]
                    mutex.Unlock()
                    atomic.AddInt64(&ops, 1)
             //为了确保这个 Go 协程不会在调度中饿死,我们在每次操作后明确的使用 runtime.Gosched()进行释放。这个释放一般是自动处理的,像例如每个通道操作后或者 time.Sleep 的阻塞调用后相似,但是在这个例子中我们需要手动的处理。
    
                    runtime.Gosched()
                }
            }()
        }
      //同样的,我们运行 10 个 Go 协程来模拟写入操作,使用和读取相同的模式。
    
        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()
                }
            }()
        }
      //让这 10 个 Go 协程对 state 和 mutex 的操作运行 1 s。
    
        time.Sleep(time.Second)
      //获取并输出最终的操作计数。
    
        opsFinal := atomic.LoadInt64(&ops)
        fmt.Println("ops:", opsFinal)
      //对 state 使用一个最终的锁,显示它是如何结束的。
    
        mutex.Lock()
        fmt.Println("state:", state)
        mutex.Unlock()
    }

    Result:

    $ go run mutexes.go
    ops: 3598302
    state: map[1:38 4:98 2:23 3:85 0:44]

    运行这个程序,显示我们对已进行了同步的 state 执行了3,500,000 次操作。

    坐标: 上一个例子   下一个例子

     

  • 相关阅读:
    HDU 4472 Count DP题
    HDU 1878 欧拉回路 图论
    CSUST 1503 ZZ买衣服
    HDU 2085 核反应堆
    HDU 1029 Ignatius and the Princess IV
    UVa 11462 Age Sort
    UVa 11384
    UVa 11210
    LA 3401
    解决学一会儿累了的问题
  • 原文地址:https://www.cnblogs.com/yhleng/p/11771087.html
Copyright © 2011-2022 走看看