go并发
go并发
2021年3月16日
18:27
goroutine:
Go语言在语言层面天生支持并发
串行:先洗完衣服再做饭,或者先做完饭再洗衣服。
并发:一会洗衣一会做饭。
并行:把洗衣盆拿到灶边,一只手做饭另一只手洗衣。
• 传统的多线程模型中创建一个新的线程代价高昂8M。
• Go语言中,每一个并发的执行单元叫作一个goroutine(协程)。类比轻量级的线程2kb
Go语言中的操作系统线程和goroutine的关系:
1. 一个操作系统线程对应用户态多个goroutine。
2. go程序可以同时使用多个操作系统线程。(Go1.5版本之前,默认使用的是单核心执行。Go1.5版本之后,默认使用全部的CPU逻辑核心数。)
3. goroutine和OS线程是多对多的关系,即m:n。
使用goroutine:
在调用的函数(普通函数和匿名函数)前面加上一个go关键字
串行:
func hello() { fmt.Println("Hello Goroutine!") } func main() { hello()
fmt.Println("main goroutine done!") }
利用goroutine并行或并发:
func main() { go hello() // 启动另外一个goroutine去执行hello函数 fmt.Println("main goroutine done!") }
多个goroutine的同步:
1.time.Sleep()指定程序等待时间。不建议
2.sync.WaitGroup
var wg sync.WaitGroup func hello(i int) { defer wg.Done() // goroutine结束就登记-1 fmt.Println("Hello Goroutine!", i) } func main() { for i := 0; i < 10; i++ { wg.Add(1) // 启动一个goroutine就登记+1 go hello(i) } wg.Wait() // 等待所有登记的goroutine都结束 }
(每次打印的数字的顺序都不一致,因为这里10个goroutine是并发执行的)
GOMAXPROCS:
Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个OS线程来同时执行Go代码。默认值是机器上的CPU核心数。例如在一个8核心的机器上,调度器会把Go代码同时调度到8个OS线程上(GOMAXPROCS是m:n调度中的n)。
Go语言中可以通过runtime.GOMAXPROCS()函数设置当前程序并发时占用的CPU逻辑核心数。
channel:
函数与函数间需要交换数据才能体现并发执行函数的意义
Go 语言中的通道(channel)是一种特殊的类型。通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。
创建 通道是引用类型,通道类型的空值是nil ,make()中第二个参数是缓冲区大小
ch := make(chan int,10)
发送
ch <- 10 // 把10发送到ch中
接受
x := <- ch // 从ch中接收值并赋值给变量x
<-ch // 从ch中接收值,忽略结果
关闭(通道是可以被垃圾回收机制回收)
close(ch)
· 对于关闭后的通道: 进行发送操作——panic异常
进行接收操作——正常接受之前已发送的数据
package main import "fmt" func main() { // var ch1 chan int // ch1=make(chan int,1) //ch1 := make(chan int) //无缓冲区通道(同步通道),必须当场立即传送值 ch1 := make(chan int, 1) ch1 <- 10 x := <-ch1 fmt.Println(x) close(ch1) // len(ch1) 数量 // cap(ch1) 容量 }
不带缓存的Channels:
• 无缓存Channels的发送操作将导致发送者goroutine阻塞,直到另一个goroutine在相同的Channels上执行接收操作。
• 如果接收操作先发生,那么接收者goroutine也将阻塞,直到有另一个goroutine在相同的Channels上执行发送操作。
• 当发送的值通过Channels成功传输之后,两个goroutine可以继续执行后面的语句。
单向通道:
限制通道在函数中只能发送或只能接收
只能发送
func counter(out chan<- int){}
只能接收
func printer(in <-chan int){}