Golang并发

协程的使用:

  • func()执行一个函数
  • go func() 开启一个协程执行函数

1. 信道chan

var pipline chan int
pipline:=make(chan int)
//发送数据
pipline<-1
//接收数据
data:=<-pipline
//关闭信道
close(pipline)
//ok表示chan是否被关闭,ok==true代表关闭
x,ok:=<-pipline

参数:

  • chan类型
  • chan容量(默认为0)

无缓冲信道:信道中不能存放数据,发送时必须被马上接收,若没有会被阻塞(同步)
有缓冲信道:可以缓存x个数据,用于多协程共享资源(异步)

双向信道:默认情况为双向信道,既可以接收也可以发送
单向信道:分为只读信道和只写信道

  • 只读信道
var pipline = make(chan int)
type Receiver = <-chan int // 关键代码:定义别名类型
var receiver Receiver = pipline
  • 只写信道
var pipline = make(chan int)
type Sender = chan<- int  // 关键代码:定义别名类型
var sender Sender = pipline

遍历信道:

pipline := make(chan int, 10)
for x :=range pipline{
}

信道传递的值是否为深拷贝,取决于类型是引用类型还是值类型
从已关闭的 channel 读取消息不会产生 panic,且能读出 channel 中还未被读取的消息,若消息均已被读取,则会读取到该类型的零值。
从已关闭的 channel 读取消息永远不会阻塞,并且会返回一个为 false 的值

2. WaitGroup

实现一主多子的协程协作方式,使用 sync.WaitGroup
var group sync.WaitGroup
方法:

  • Add 初始值为0,计数器加一,直接传入子协程的数量
  • Done 某个子协程完成后调用该方法,计数器减一,通常通过defer调用
  • Wait 阻塞当前协程,直到计数器归零

3. Golang锁

3.1 互斥锁 Mutex

目的:保护一个资源不会因为并发而引起冲突

//定义
var lock *sync.Mutex
lock=new(sync.Mutex)

lock:=&sync.Mutext{}
//加锁
lock.Lock()
//解锁
lock.Unlock()
3.2 读写锁 RWMutex

将程序对资源的访问分为读操作和写操作

  • 为了保证数据的安全,其它协程写数据会阻塞
  • 多协程读数据互不影响,不阻塞,不同于Mutex,只允许一个协程读数据
//定义
var lock *sync.RWMutex
lock=new(sync.RWMutex)

lock:=&sync.RWMutext{}
//加锁
lock.RLock()//读锁
lock.Lock()//写锁
//解锁
lock.RUnLock()
lock.Unlock()

4. Golang Context

当需要手动控制协程(关闭)的情况下,需要使用context

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key interface{}) interface{}
}

方法:

  • Deadline,返回[截止时间,布尔值(true表示设置了截止时间)]
    到了截止时间,自动触发Cancel,若没有截止时间,需要手动调用Cancel取消Context
  • Done,返回一个只读的chan,类型为struct{},被cancel后会返回,若可读,意味着发起了cancel
  • Err,返回cancel的原因
  • Value,返回被绑定到Context的值,是一个键值对
    Context
var (
    background = new(emptyCtx)
    todo       = new(emptyCtx)
)
func Background() Context {
    return background
}
func TODO() Context {
    return todo
}

Background: 用于main函数,初始化以及测试代码中,作为Context树结构的顶层Context,不能被取消
TODO:不知道该用什么Context时可以使用
本质上都是emptyCtx结构体类型,不可取消,无截止时间,不携带值的Context
Context继承衍生

func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
func WithValue(parent Context, key, val interface{}) Context

实现线程池
Golang Context
通道模型

posted @ 2022-04-21 09:36  流光之中  阅读(62)  评论(0编辑  收藏  举报