go语言工程进阶之并发编程 | 青训营笔记
这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
并发编程
go语言的流行的重要原因之一就是其自带并发编程,那么
并发和并行有什么区别呢?
并行:多线程的程序在cpu的一个核上运行
并发:多线程的程序在cpu的多个核上运行
因此,go语言能充分发挥现代计算机多核心cpu的特点,从而大大提高运行效率
协程 Goroutine和线程是什么关系?
协程:用户态,轻量级线程 栈MB级别
线程:内核态,线程跑多个协程,栈KB级别
线程占用系统资源大,协程的创建和调度都由go语言进行
通俗的说,就是避免多次大量的创建、切换、停止线程占用过多系统资源,改为在已有线程里多次创建调度协程来完成工作
打开协程的hello world:
package concurrence
import (
"fmt"
"time"
)
func hello(i int) {
println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
for i := 0; i < 5; i++ {
// go关键字作为创建协程的关键字
go func(j int) {
hello(j)
}(i)
}
// 保证子协程运行完前主线程不退出
time.Sleep(time.Second)
}
并发模型CSP(communicating sequential processes)
主打的就是一个叛逆,通过通信来共享内存
缓冲通道Channel
通道是用来传递数据的一个数据结构,可以用于两个协程之间,通过传递一个指定类型的值来同步运行和通讯
操作符
<-用于指定通道的方向,实现发送or接收若未指定方向,则为双向通道
当然还分为
-
无缓冲通道 make(chan int)
-
有缓冲通道 make(chan int, 2)
通过两个Channel通道完成数字平方任务案例:
package concurrence
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)
}
}