• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go语言从例子开始之Example36.互斥锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器。对于更加复杂的情况,我们可以使用一个互斥锁来在 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 次操作。

 

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

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go中的指针发布时间:2022-07-10
下一篇:
go语言的array、slice和map发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap