并发编程目录

72 阅读1分钟

概述

为什么会出现

如果进程同时只能处理一件事,在等待资源(耗时计算、IO)时也不能处理其他任务,会导致工作效率低,cpu空闲时间较长,为了能充分利用cpu加快任务处理效率,就需要多线程处理任务

遇到问题

  • 公共资源竞争
  • 线程间数据交互
  • 任务编排

原因

  • 逻辑不是原子操作
  • 系统优化,指令重排序
  • 缓存,数据没马上同步

解决方案

  • 临界区加锁,加锁区变成原子操作,同时不会指令重排

使用会引发的问题与优化

  • 死锁,不同线程死锁,锁重入问题
  • 公平问题,锁饥饿
  • 自旋
  • try lock

工具

  • race,查找存在竞争的资源 go run -race xxx.go,编译插入检查代码
  • vet 工具检查死锁问题,代码静态分析

基本并发原语

Mutex 锁

RWMutex 读写锁

Waitgroup

Cond

wait/notify模型,用Waitgroup或者channel替换,基本不会使用

Once

可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场景

var once sync.Once
once.Do(f func)

Pool

Context

原子操作

Channel

扩展并发原语

信号量、SingleFlight、循环栅栏、ErrGroup

分布式并发原语

分布式并发原语是应对大规模的应用程序中并发问题的并发类型。我主要会介绍使用 etcd 实现的一些分布式并发原语,比如 Leader 选举、分布式互斥锁、分布式读写锁、分布式队列等,在处理分布式场景的并发问题时,特别有用