go并发编程-路线总结3

本文介绍了Go语言中用于任务编排的并发工具,如ErrGroup、gollback、Hunch等,以及分布式并发控制的机制如etcd、互斥锁、队列、STM等,展示了如何利用这些工具提高程序并发度和管理异步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分组操作

分组执行一批相同的或类似的任务则是任务编排中一类情形

ErrGroup

将一个大的任务拆成几个小任务并发执行,可以有效地提高程序的并发度

方法

  • WithContext
    • 返回一个 Group 实例和 context.WithCancel(ctx) 生成的新 Context
    • 子任务返回错误,或者是 Wait 调用返回,这个新 Context 就会被 cancel
  • Go
    • 传入子任务函数 f ,成功,返回 nil,否则返回 error,并且 cancel 这个新的 Context。
  • Wait
    • 等所有子任务都完成,才会返回,否则阻塞等待。
    • 有多个子任务返回错误,只会返回第一个出现的错误,所有的子任务都执行成功,返回 nil

gollback

用来处理一组子任务的执行的,它解决了 ErrGroup 收集子任务返回结果的痛点

方法

  • All

    • 它会等待所有的异步函数(AsyncFunc)都执行完才返回
    • 而且返回结果的顺序和传入的函数的顺序保持一致。
  • Race

    • 只要一个异步函数执行成功,就立马返回。同时会把其它子任务的 Context cancel掉,这样子任务就可以中断自己的执行。
    • 所有子任务都没有成功,就返回最后一个 error 信息。
  • Retry

    • 执行一个子任务,如果子任务执行失败,它会尝试一定的次数,如果一直不成功 ,就会返回失败错误 ,如果执行成功,它会立即返回。
    • 如果retires 等于 0,它会永远尝试,直到成功

Hunch

Hunch提供的功能和 gollback 类似,不过它提供的方法更多

方法

  • All
    • 传入一组可执行的函数(子任务),返回子任务的执行结果
    • 一旦一个子任务出现错误,它就会返回错误信息
  • Take
    • 指定 num 个子任务正常执行完没有错误,就会返回这几个子任务的结果。
    • 一旦一个子任务出现错误,它就会返回错误信息
  • Last
    • 返回最后 num 个正常执行没有错误的子任务的结果(和Take相反)。
    • 一旦一个子任务出现错误,它就会返回错误信息
  • Retry
    • 和 gollback 的 Retry 方法的功能一样
  • Waterfall
    • 所有的子任务都是串行执行的,前一个子任务的执行结果会被当作参数传给下一个子任务,直到所有的任务都完成,返回最后的执行结果。
    • 一旦一个子任务出现错误,它就会返回错误信息

schedgroup

指定一组 goroutine在某个时间或者某个时间之后执行

方法

  • Delay 和 Schedule
    • 指定在某个时间或者之后执行一个函数
    • Delay time.Duration 参数
    • Schedule 指定明确的某个时间执行
  • Wait
    • 阻塞,直到之前安排的所有子任务都执行完才返回
    • Context被取消,Wait 方法会返回这个 cancel error。
    • 调用 Wait ,就不能调用它的 Delay 和 Schedule ,会 panic。
    • 只能调用一次,多次调用会 panic。

分布式并发原语etcd

Leader 选举

  • 选举
  • 查询
  • 监控

互斥锁

同一时刻,只允许其中的一个节点持有锁

  • Locker
    • 类似于 Go 标准库中的 sync.Locker 接口,提供了 Lock/UnLock 的机制,基于 Mutex 实现
  • Mutex
    • 提供了Lock/UnLock和查询 Mutex 的key 的信息的功能
  • 读写锁
    • 和标准库的读写锁的功能是一样的

队列

分布式队列

多读多写的队列,可以启动多个写节点和多个读节点

优先级队列

和队列类似,写入元素需要提供 uint16 整数优先级,优先级高优先出队。

栅栏

Barrier:分布式栅栏

持有 Barrier 的节点释放了它,所有等待这个 Barrier 的节点才会继续执行

DoubleBarrier:计数型栅栏

初始化计数型栅栏时,就必须提供参与节点的数量,当这些数量的节点都 Enter 或者 Leave 的时候,这个栅栏就会放开

STM(事务)

  • 简化多个key的操作,并且提供事务功能(要么全成功,要么全失败)
  • 方法:Get、Put、Receive 和 Delete

内存模型

并发环境中多goroutine 读相同变量的时候,变量的可见性条件

happens-before

goroutine 内部,程序的执行顺序和它们的代码指定的顺序是一样的

go语言中保证的happens-before关系

  • init 函数
    • init函数一定在当前包的任何初始化代码之前执行
  • goroutine
    • 启动 goroutine 的 go 语句的执行,一定发生在此 goroutine 内的代码之前执行
    • 根据此规则,go 语句传入的参数是一个函数执行的结果,那么,这个函数一定先于 goroutine 内部的代码被执行。(参数结果从传入的时候就固定了)
  • Channel
    • 对 Channel 的第n个发送操作,一定发生在第n个接收操作之前
    • close Channel 的操作,一定发生在从 Channel中读取出零值之前。
    • 对无缓冲的Channel的读取操作,一定发生在此Channel的发送操作之前
  • Mutex/RWMutex
    • 解锁操作一定发生在下次上锁操作之前
  • WaitGroup
    • Wait 方法等到计数值归零之后才返回
  • Once
    • once.Do(f) 调用,函数 f 一定会在任何 Do 方法返回之前执行
  • atomic
    • Store 一定在Load之前执行,但是太过于复杂,现阶段还是不要使用 atomic 来保证顺序性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值