这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天
并发与并行
并发是指多线程程序在一个核的CPU上运行,在同一时间点,任务不会同时运行。
并行是指多线程程序在多个核的CPU上运行,在同一时间点,任务一定是同时运行。
goroutine(协程)
goroutine 是 Go语言中的轻量级线程实现,由 Go 运行时(runtime)管理。Go 程序会智能地将 goroutine 中的任务合理地分配给每个 CPU。
Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。
线程: 内核态,线程跑多个协程,栈MB级别。
协程: 用户态,轻量级线程,栈KB级别。
为一个普通函数创建 goroutine 的写法如下:
go 函数名( 参数列表 )
package main
import (
"fmt"
"time"
)
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
go func(j int) {
hello(j)
}(i)
}
time.Sleep(time.Second)
}
func main() {
HelloGoRoutine()
}
CSP (Communicating Sequential Processes)
在go语言中,协程之间通过通信来实现共享内存。
通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。
创建通道
make(chan 元素类型, [缓冲大小])
- 无缓冲通道 make(chan int)
- 有缓冲通道 make(chan int, 2)
使用通道发送数据
通道发送数据的格式
通道的发送使用特殊的操作符<-,将数据通过通道发送的格式为: 通道变量 <- 值
通道变量:通过make创建好的通道实例。
值:可以是变量、常量、表达式或者函数返回值等。值的类型必须与ch通道的元素类型一致。
// 创建一个空接口通道
ch := make(chan interface{})
// 将0放入通道中
ch <- 0
// 将hello字符串放入通道中
ch <- "hello"
package main
func CalSquare() {
src := make(chan int)
dest := make(chan int, 3)
// 生产
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
// 消费
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
}
func main() {
CalSquare()
}