Golang入门学习(13)
Go的第13课——Go 并发
这几天元旦在外面浪呢,也是很长一段时间没有学习,今天来补补。
go并发编程
协程
Golang中的并发是 函数 相互独立运行的能力。Goroutines是并发运行的函数。Golang提供了Goroutines作为并发处理操作的一种方式。
创建一个协程非常简单,就是在一个任务函数前面添加一个go关键字:
1 | go function(1,2,3) |
相当于是让 function 异步执行,后续语句不等待 function(1,2,3)
执行完毕。
就相当于是开一个线程去执行函数内容,等同于 python 中的 threading.Thread(target=funciton,args=[1,2,3]).start()
实例
为了起到效果,是用了 time 包里的 sleep 函数。
1 | package main |
运行结果为交替输出,这就是并发编程。
通道(channel)
介绍
Go 提供了一种称为通道的机制,用于在 goroutine 之间共享数据。当您作为goroutine 执行并发活动时,需要在goroutine之间共享资源或数据,通道充当goroutine之间的管道(管道)并提供一种机制来保证同步交换。
需要在声明通道时指定数据类型。我们可以共享内置、命名、结构和引用类型的值和指针。数据在通道上传递:在任何给定时间只有一个 goroutine 可以访问数据项:因此按照设计不会发生数据竞争。
根据数据交换的行为,有两种类型的通道:无缓冲通道和缓冲通道。无缓冲通道用于执行goroutine 之间的同步通信,而缓冲通道用于执行异步通信。无缓冲通道保证在发送和接收发生的瞬间执行两个goroutine之间的交换。缓冲通道没有这样的保证。
可以理解为 socket
或者是多进程通信的 pipe
?
通道由 make函数创建,该函数指定 chan 关键字和通道的元素类型。
发送接收特性
所谓有缓冲区就是指可以建立一个临时的缓冲区,收和发可以不同步,我发了一个消息可以等你上线查看,无缓冲区就是指你必须立刻接收这些消息,没有缓冲区留存数据,发的时候你要是没有在接收那就没有了,当然在这里他会强制发的人等待接收的人做接收动作,或者是等待发的人发出消息。
- 对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的。
- 发送操作和接收操作中对元素值的处理都是不可分割的。
- 发送操作在完全完成之前会被阻塞。接收操作也是如此。
语法
1 | Unbuffered:= make(chan int)//整型无缓冲通道 |
使用内置函数 make 创建无缓冲和缓冲通道。make 的第一个参数需要关键字 chan,然后是通道允许交换的数据类型。
发送数据:
1 | channel<-data |
接收数据:
1 | data:=<-channel |
示例
1 | package main |
协程同步
使用 WaitGroup 来进行协程同步。
sync.WaitGroup类
1 | package main |
同时我们可以观察观察 wg.Wait() 这句删除之后会发生什么,极大概率是只会输出一个 Done… 的,因为主线程结束之后所有协程不管在哪都默认 kill 了不会输出任何内容。