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 次操作。
go语言从例子开始之Example36.互斥锁的更多相关文章
- 学习Go语言之使用原子访问或互斥锁解决竞态问题
使用原子访问或互斥锁 // 解决竞态问题 package main import ( "fmt" "sync" "sync/atomic" ...
- day34 python学习 守护进程,线程,互斥锁,信号量,生产者消费者模型,
六 守护线程 无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁 需要强调的是:运行完毕并非终止运行 #1.对主进程来说,运行完毕指的是主进程代码运行完毕 #2.对主线程来说,运行完 ...
- [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程
一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...
- Go语言基础之13--线程安全及互斥锁和读写锁
一.线程安全介绍 1.1 现实例子 A. 多个goroutine同时操作一个资源,这个资源又叫临界区 B. 现实生活中的十字路口,通过红路灯实现线程安全 C. 火车上的厕所(进去之后先加锁,在上厕所, ...
- go语言从例子开始之Example37.Go 状态协程
在前面的例子中,我们用互斥锁进行了明确的锁定来让共享的state 跨多个 Go 协程同步访问.另一个选择是使用内置的 Go协程和通道的的同步特性来达到同样的效果.这个基于通道的方法和 Go 通过通信以 ...
- gRPC in ASP.NET Core 3.x -- Protocol Buffer(2)Go语言的例子(下)
第一篇文章(大约半年前写的):https://www.cnblogs.com/cgzl/p/11246324.html gRPC in ASP.NET Core 3.x -- Protocol Buf ...
- 006_go语言中的互斥锁的作用练习与思考
在go语言基本知识点中,我练习了一下互斥锁,感觉还是有点懵逼状,接下来为了弄懂,我再次进行了一些尝试,以下就是经过我的尝试后得出的互斥锁的作用. 首先还是奉上我改造后的代码: package main ...
- 037_go语言中的互斥锁
代码演示: package main import ( "fmt" "math/rand" "runtime" "sync&quo ...
- Go语言中的互斥锁和读写锁(Mutex和RWMutex)
目录 一.Mutex(互斥锁) 不加锁示例 加锁示例 二.RWMutex(读写锁) 并发读示例 并发读写示例 三.死锁场景 1.Lock/Unlock不是成对出现 2.锁被拷贝使用 3.循环等待 虽然 ...
随机推荐
- php array_search()函数 语法
php array_search()函数 语法 作用:在数组中搜索某个键值,并返回对应的键名.dd马达生产厂家 语法:array_search(value,array,strict) 参数: 参数 描 ...
- 关于富文本复制word,里面掺杂图片上传的问题
图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM ...
- 虚拟机CentOS7安装docker并搭建Gitlab私服
一.下载安装虚拟机和CentOS7系统 这些流程比较简单不会有什么坑,这里不再阐述 二.安装docker 1.Docker 要求 CentOS 系统的内核版本高于 3.10 ,查看本页面的前提条件来验 ...
- Solr基本命令
启动Solr 安装Solr后,进入到Solr主目录中的bin文件夹,并使用以下命令启动Solr. [Hadoop@localhost ~]$ cd [Hadoop@localhost ~]$ cd S ...
- ECharts t图表组件使用心得
1.使用较多的是“柱状图”和“折线图”: 2.数据列的展示不能够直接输入字符串,正确的做法是将字符串转换成数字类型,这样在生成的图表上才会显示最大值和最小值: 3.对上 1 点的补充,数据列应该使用数 ...
- php mysql-pdo,fpm,csrf-forward-money,php7.1 in centos7
centos7--php7.1http://zixuephp.net/article-207.htmlhttps://www.cnblogs.com/liansng/p/7680930.html ph ...
- vue-lazyload 图片不更新
前几天在用vue写项目的时候,因为图片比较多,所以采用了懒加载插件 vue-lazyload github:https://github.com/hilongjw/vue-lazyload#readm ...
- EZOJ #385 排列
分析 对于第一问我们直接从上到下枚举所有横边 每一次交换两边的列标号即可 对于第二问我们发现答案就是最终序列的逆序对数量 代码 #include<bits/stdc++.h> using ...
- Duplicate entry '4799' for key 'PRIMARY'
增加1条SQL记录报错: Operation failed: There was an error while applying the SQL script to the database. Exe ...
- 用Delphi从内存流中判断图片格式[转]
http://blog.163.com/tfn2008%40yeah/blog/static/110321319201222243214337/ 用Delphi从内存流中判断图片格式[转] 2012- ...