Go 并发

Posted 奋斗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go 并发相关的知识,希望对你有一定的参考价值。

1. 线程

开始线程只需要使用go关键字即可

2. 线程等待

主线程需要所有子线程执行完成后才结束

线程等待包 sync.WaitGroup
添加等待线程数 waitGroup.Add(100)
子线程结束标志 waitGroup.Done()
主线程等待标志 waitGroup.Wait()

import (
   "fmt"
   "sync"
)

func main() 
   var waitGroup sync.WaitGroup
   // 添加需要等待线程的数量
   waitGroup.Add(100)
   for i := 0; i < 100; i++ 
      // 开启线程
      go func(x int) 
         // defer定义的每次执行完成之前减少线程等待数量
         defer waitGroup.Done()
         fmt.Println(x)
      (i)
   
   // 等待子线程结束 在执行后面的逻辑
   waitGroup.Wait()

3.线程锁

防止线程中重要逻辑还没完成就切换线程导致的错误

  • sync.Mutex
import (
   "fmt"
   "sync"
)

var waitGroup sync.WaitGroup
var lock sync.Mutex
var total int32

func main() 
   waitGroup.Add(2)
   go add()
   go sub()
   waitGroup.Wait()
   fmt.Println(total)

func add() 
   defer waitGroup.Done()
   for i := 0; i < 100000; i++ 
      // 计算前加锁
      lock.Lock()
      total += 1
      // 计算后解锁
      lock.Unlock()
   

func sub() 
   defer waitGroup.Done()
   for i := 0; i < 100000; i++ 
      lock.Lock()
      total -= 1
      lock.Unlock()
   

  • atomic原子锁

需要传指针类型

import (
   "fmt"
   "sync"
   "sync/atomic"
)

var waitGroup sync.WaitGroup
var lock sync.Mutex
var total int32

func main() 
   waitGroup.Add(2)
   go add()
   go sub()
   waitGroup.Wait()
   fmt.Println(total)

func add() 
   defer waitGroup.Done()
   for i := 0; i < 100000; i++ 
      // 需要注意的是这块的值是指针
      atomic.AddInt32(&total, 1)
   

func sub() 
   defer waitGroup.Done()
   for i := 0; i < 100000; i++ 
      // 需要注意的是这块的值是指针
      atomic.AddInt32(&total, -1)
   

以上是关于Go 并发的主要内容,如果未能解决你的问题,请参考以下文章

Go CSP并发模型

gin go并发案例

图解 Go 并发

Go语言基础之并发

Go语言之Go语言并发

09. Go 语言并发