go并发学习笔记--协同

原创
2021/10/23 23:26
阅读数 198

概述

      谈到go,可能你第一个想到的是goroutine,常见是的关键词:百万级,无锁。那么就会有goroutine间协同交互的。首先简单了解一下并发的发展历史:  

共享内存-管道技术(CSP(通信顺序进程,Communicating Sequential Process) --> PIPE --> Unix系统中的管道),然后看看go是如何实现的:

  • 原子操作 atomic 
  • 互斥体
    • sync.Mutex
    • sync.RWMutex
  • 等待组 sync.WaitGroup
  • 条件变量 sync.Cond
  • 管道 io.Pipe channel

详细介绍和注意点

  1.  原子操作: cpu保证原子性,与多个goroutine无关 
  2. 互斥体(sync.Mutex,sync.RWMutex):锁
    1. 常见问题1: 加锁后忘记解锁,可以defer 加锁和解锁成套使用,避免因为写错或者panic产生死锁
      1. mutex.Lock
      2. defer mutex.Unlock
      3. doSth()
    2. 常见问题2:在锁之间执行长耗时的操作,导致产生跟死锁一样的情况发生。
    3. 错误认知,channel一定比锁性能好。本身锁的性能仅此原子操作
  3. 等待组 sync.WaitGroup:适用多个需要等待多个任务都完成的情况 

    func (wg *WaitGroup) Add(n int)
    func (wg *WaitGroup) Done()
    func (wg *WaitGroup) Wait()

  4. 条件变量 sync.Cond

    func NewCond(l Locker) *Cond
    func (c *Cond) Broadcast()
    func (c *Cond) Signal()
    func (c *Cond) Wait()

  5. 管道 io.Pipe channel 

    c := make(chan Type, n) // 创建一个能够传递 Type 类型数据的管道,缓冲大小为 n
    ...
    go func() {
        val := <-c // 从管道读入
    }()
    ...
    go func() {
        c <- val // 向管道写入
    }()

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部