go语言从例子开始之Example35.互斥锁
时间:2019-10-31
本文章向大家介绍go语言从例子开始之Example35.互斥锁,主要包括go语言从例子开始之Example35.互斥锁使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
在前面的例子中,我们看到了如何使用原子操作来管理简单的计数器。对于更加复杂的情况,我们可以使用一个互斥锁来在 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 次操作。
坐标: 上一个例子 下一个例子
原文地址:https://www.cnblogs.com/yhleng/p/11771087.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP设计模式之中介者模式(Mediator Pattern)入门与应用案例详解
- laravel 出现command not found问题的解决方案
- PHP怎么搭建百度Ueditor富文本编辑器
- 使用composer命令加载vendor中的第三方类库 的方法
- PHP批斗大会之缺失的异常详解
- Laravel 6.2 中添加了可调用容器对象的方法
- php实现微信企业转账功能
- 在 Laravel 6 中缓存数据库查询结果的方法
- PHP操作XML中XPath的应用示例
- Laravel手动返回错误码示例
- laravel添加前台跳转成功页面示例
- PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
- thinkPHP利用ajax异步上传图片并显示、删除的示例
- Yii框架where查询用法实例分析
- PHP命名空间(namespace)原理与用法详解