go语言笔记(并发编程)

go语言笔记(并发编程)

协程Goroutines

  • 每个go程序至少都有一个Goroutine:主Goroutine(在运行进程时自动创建)。以及程序中其他Goroutine

  • 在go中有个package是sync,里面包含了:WaitGroup、Mutex、Cond、Once、Pool,下面依次介绍。

WaitGroup

  • WaitGroup中的Add(n)把计数器设置为n,Done()会将计数器每次减1,Wait()函数会阻塞代码运行,直到计数器减0。等待多个goroutine完成,可以使用一个等待组。
// 这是我们将在每个goroutine中运行的函数。
// 注意,等待组必须通过指针传递给函数。
func worker(id int, wg *sync.WaitGroup) {

	defer wg.Done()

	fmt.Printf("Worker %d starting\n", id)

	time.Sleep(time.Second)
	fmt.Printf("Worker %d done\n", id)
}

func main() {

	var wg sync.WaitGroup

	for i := 1; i <= 5; i++ {
		wg.Add(1)
		go worker(i, &wg)
	}

	wg.Wait()
}

这里首先把wg 计数设置为1, 每个for循环运行完毕都把计数器减一,主函数中使用Wait() 一直阻塞,直到wg为1——也就是所有的5个for循环都运行完毕。

Once

  • sync.Once可以控制函数只能被调用一次,不能多次重复调用。
var doOnce sync.Once

func main() {
	DoSomething()
	DoSomething()
}

func DoSomething() {
	doOnce.Do(func() {
		fmt.Println("Run once - first time, loading...")
	})
	fmt.Println("Run this every time")
}

互斥锁Mutex

  • 互斥锁是并发程序对共享资源进行访问控制的主要手段,在go中的sync中提供了Mutex的支持。
  • sync.RWMutex分为:读、写锁。在读锁占用下,会阻止写,但不会阻止读,多个goroutine可以同时获取读锁,调用RLock()函数即可,RUnlock()函数释放。写锁会阻止任何goroutine进来,整个锁被当前goroutine,此时等价于Mutex,写锁调用Lock启用,通过UnLock()释放。

条件变量Cond

  • sync.Cond是条件变量,它可以让一系列的 Goroutine 都在满足特定条件时被唤醒。

    条件变量通常与互斥锁一起使用,条件变量可以在共享资源的状态变化时通知相关协程。

  • 例如:使用WaitGroup等待两个Goroutine完成,
    Goroutine1与Goroutine2进入Wait状态,main函数在2s后改变共享数据状态,调用Broadcast函数,此时c.Wait从中恢复并判断条件变量是否已经满足,满足后消费条件,解锁,wg.Done()。

原子操作

  • 原子操作即是进行过程中不能被中断的操作。针对某个值的原子操作在被进行的过程中,CPU绝不会再去进行其他的针对该值的操作。
    为了实现这样的严谨性,原子操作仅会由一个独立的CPU指令代表和完成。
  • 在sync/atomic 中,提供了一些原子操作,包括加法(Add)、比较并交换(Compare And Swap,简称(CAS)、加载(Load)、存储(Store)和交换(Swap)。

临时对象池Pool

  • sync.Pool 可以作为临时对象的保存和复用的集合
  • P是Goroutine中的重要组成之一,例如:P实际上在操作时会为它的每一个goroutine相关的P生成一个本地P。本地池没有,则会从其它的 P 本地池获取,或者全局P取。
  • sync.Pool对于需要重复分配、回收内存的地方,sync.Pool
    是一个很好的选择。减少GC负担,如果Pool中有对象,下次直接取,不断服用对象内存,减轻 GC 的压力,提升系统的性能。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值