教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 sync.WaitGroup和sync.Mutex的简单用法

sync.WaitGroup和sync.Mutex的简单用法

发布时间:2023-03-24   编辑:jiaochengji.com
教程集为您提供sync.WaitGroup和sync.Mutex的简单用法等资源,欢迎您收藏本站,我们将为您提供最新的sync.WaitGroup和sync.Mutex的简单用法资源

CSP 是 Communicating Sequential Process 的简称,中文可以叫做通信顺序进程,是一种并发编程模型,最初于Tony Hoare的1977年的论文中被描述,影响了许多编程语言的设计。

golang CSP模型

golang语言并没有完全实现了CSP模型的所有理论,仅仅是借用了 process和channel这两个概念。process是在golang语言上的表现就是 goroutine, 是实际并发执行的实体,每个实体之间是通过channel通讯来实现数据共享。
最经典的数据通信共享理论

以通信的方式来共享内存

Do not communicate by sharing memory; instead, share memory by communicating

不要以共享内存的方式来通信,相反,要通过通信来共享内存。
这是golang实现高并发的基础通信理论。
在golang语言上面,就是通过channel实现多个goroutine的数据通信。

sync.WaitGroup使用

如果需要让多个goroutine都执行完成,就是用使用time.sleep,延迟几秒保证每个goroutine都能执行到。

func testPrint(i int) {
	fmt.Println(i)
}
func main() {
	for i:=0;i<5;i   {
		go testPrint(i)
	}
	time.Sleep(time.Second)
}

但是在生产项目里面就没法这么写了,延迟1S有可能所有goroutine没执行完成,延迟1000S可能1毫秒就执行完了,其他999S都是等待,延长了程序执行时间。
所以就有sync.WaitGroup

func testPrint(wg *sync.WaitGroup, i int) {
	fmt.Println(i)
	wg.Done()
}
func main() {
	var wg = new(sync.WaitGroup)
	for i:=0;i<5;i   {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
}

WaitGroup比较容易理解,其实就是一个内部计数器,在执行goroutine行为之前执行 wg.Add(1),给计数器 1,执行完之后,执行wg.Done(),表示这个goroutine执行完成,计数器内部-1,wg.Wait()会阻塞代码的运行,等待所有的添加进WaitGroup的goroutine全部执行完毕(计数器减为0),再退出程序。
非常完美的解决了等待所有goroutine执行完毕的需要。

sync.Mutex

sync.Mutex,互斥锁排它锁。
我们需要维护一个变量,保证每个goroutine都能成功的修改它,如果没有互斥锁可能就是下面的代码

func testPrint(wg *sync.WaitGroup, i int) {
	count  
	fmt.Println(i)
	wg.Done()
}
var count int
func main() {
	count = 0
	var wg = new(sync.WaitGroup)
	for i:=0;i<500;i   {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
	fmt.Printf("count:%d",count)
}

预期应该是特定的值,500,其实经常性的不是500.就是因为多个goroutine同时去修改count值了,加上互斥锁试一下。

func testPrint(wg *sync.WaitGroup, i int) {
	defer func() {
		mu.Unlock()
	}()
	mu.Lock()
	count  
	fmt.Println(i)
	wg.Done()
}
var count int
var mu *sync.Mutex
func main() {
	count = 0
	mu = new(sync.Mutex)
	var wg = new(sync.WaitGroup)
	for i:=0;i<500;i   {
		wg.Add(1)
		go testPrint(wg,i)
	}
	wg.Wait()
	fmt.Printf("count:%d",count)
}

结果是定值500,跟预想的一致。

到此这篇关于“sync.WaitGroup和sync.Mutex的简单用法”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang模仿七牛图片处理API
Go 标准库 —— sync.Mutex 互斥锁
go golang 笔试题 面试题 笔试 面试
2020-10-19Go语言goroutine和channel
go二维map_Golang使用Map的正确姿势
Go语言基础(3)
编程书说的“Go程序员应该让聚合类型的零值也具有意义”是在讲什么
Golang sync.WaitGroup源码详细分析
一道并发和锁的golang面试题
golang语言异步通信之WaitGroup

[关闭]
~ ~