代码
调试技术
数据库
- 《Getting started with impala》
- 《mysql 必知必会》
- 《mysql 性能调优与架构实践》
- 《Mysql 技术内幕 InnoDB 存储引擎》
- 《Redis 实战》
- 《Redis 深度历险核心原理和应用实践》
- 《redis设计与实现》
- 《七周七数据库》
- 《深入浅出mysql》
- 《高性能mysql第三版》
- 《MySQL是怎样运行的》
前端
GOLANG
- 《1 The Go Programming Language》
- 《2 The Go Programming Language》
- 《3 The Go Programming Language》
- 《Build Web Application With Golang》
- 《Go101》
- 《Network Programming with go》
- 《Building Microservices With Go》
- 《Building Restful Web Services with Go》
- 《Concurrency In Go》
- 《Go In Action(Go 实战)》
- 《Go学习笔记语言详解》
- 《Go学习笔记源码剖析》
- 《Go语言编程》
JAVA
网络
心理学
PYTHON
创业
UNIX/LINUX
分布式
系统设计
搜索引擎
开发工具
- 《Practical Vim》
- 《Vim8文本处理实战》
- 《Learn vim scrpt the hard way》
- 《Pro Git》
- 《Mastering Vim》
- 《Mastering Vim Quickly》
思维
源码
网站架构微服务
- 《微服务架构设计模式》
- 《从0开始学架构》
- 《web scalavility for startup engineers》
- 《designdatainstensive_application》
- 《designdatainstensive_application2》
- 《clean_architecture》
- 《微服务实战》
- 《微服务设计》
软件工程/项目管理
运维
金融理财
写作
互联网
区块链
技术演讲网课
- 《哔哩哔哩的go微服务实战》
- 《go业务基础库之Error&Context》
- 《Go同步和并发设计模式》
- 《300分钟吃透分布式缓存》
- 《DDD实战课》
- 《分布式技术原理与实战45讲》
- 《架构设计面试精讲》
- 《高并发系统设计40问》
- 《java并发编程78讲》
- 《中间件核心技术与实战讲》
职场
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
《Go同步和并发设计模式》
基本同步原语
Mutex
- 互斥锁 Mutual exclusion
- 任何时间只允许一个 goroutine 在临界区运行
- 避免死锁
- 公平
- 零值是未锁状态
- Unlock 未加锁的 Mutex 会 panic
- 加锁的 Mutex 不和这个特定的 goroutine 关联
- 非重入锁
RWMutex
- 可以被一堆的reader持有,或者被一个 writer 持有
- 适合大并发 read 的场景
- 零值是未加锁状态
- writer 的 Lock相对后续 reader 的 RLock 优先级高
- 禁止递归读锁(防止死锁)
Cond (不常用)
- Mutex有些不适用
- Monitor vs Mutex. Monitor = Mutex + Condition Variables
- Condition variable 是一组等待同意一个条件的goroutine的容器
- 每个 cond 和一个Locker 相关联
- 改变条件或者调用 Wait 需要获取锁
WaitGroup
- 等待一组goroutine完成(java CountdownLatch/CyclicBarrier)
- Add 参数可以是负数,如果计数器小于0,panic
- 当计数器为0的时候,阻塞在 Wait 方法的 goroutine 都会被释放
- 可重用, but...
- 注意不要把Add方法放到 goroutine 里和wait 一起执行
Once
- 只执行一次初始化 func (o *Once) Do(f func())
- 避免死锁
- 即使 f panic, Once 也认为它完成了
单例 - 常量 - package 变量(eager) - init 函数 (eager) - GetInstance()(lazy) - 通过 sync.Once 或者类似实现
Pool
- 临时对象池
- 可能在任何时候任意对象都可能被移除
- 可以安全并发访问
- 装箱/拆箱
Sync.Map
- 适用于两个 case(空间换时间):
- 设置一次,多次读(cache)
- 多个 goroutine 并发的读,写,更新不同的 key
- 装箱/拆箱
- Range 进行遍历,可能会加锁
- 没有 Len 方法,并且也不会添加
扩展同步原语
ReentrantLock
type RecursiveMutext struct {
sync.Mutex
owner int64
recursion int32
}
Semaphore
- Dijkstra 提出并发访问通用资源的并发原语 (sync/semaphore)
- 初始化一个非负的值 S
- P(wait)减1,如果 S 小于0 ,阻塞本 goroutine 进入临界区
- V(signal)加1, 如果 S 不为负值, 其他goroutine可以进入临界区
- 二进制信号量可以实现锁(0,1)
- 计数信号量
实现: sync/semaphore sync/singleflight
ErrGroup
- Wait会等待所有 goroutine 执行完才释放
- 如果想遇到第一个 err 就返回,用 Context
SpinLock (自旋锁)
- 有时候很高效
- 公平性
- 处理器忙等待
fslock 文件锁
- github.com/juju/fslock
concurrent-map
- github.com/orcaman/concurrent-map
原子操作
atomic 数据类型
- int32, int64, uint32, uint64, uintptr, unsafe.Pointer
- AddXXX(整数类型)
- CompareAndSwapXXX: cas
- LoadXXX: 读取
- StoreXXX: 存储
- SwapXXX: 交换
有Add没有 Subtract?
- 有符号类型,可以用 Add 负数
- 无符号类型,可以用 AddUint32(&x, ^uint32(c-1)), AddUint64(&x, ^uint64(c-1))
- 无符号类型减一,AddUint32(&x, ^uint32(0)), AddUint64(&x, ^uint64(0))
atomic.value
复杂类型进行原子存储和加载
- Load
- Store
Channel
- 信号(shutdown/close/finish)
- 数据交流(queue/stream)
- 锁(mutex)
Channel vs Mutex
过度使用channel 和goroutine
- Channel
- 传递数据的owner
- 分发任务单元
- 交流异步结果
- 任务编排
- Mutex
- cache
- 状态
- 临界区
OrDone
内存模型
描述线程(goroutine)通过内存交互,以及对数据的共享使用。
Go内存模型:
happend before
- goroutine的创建 happens before 所有此 goroutine 中的操作
- goroutine的销毁 happens after 所有此 goroutine 中的操作
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论