这是我参与「第五届青训营」伴学笔记活动的第二天
1.并发vs并行
并发:多线程在一个核的cpu上运行,通过时间片的切换
并行:多线程程序在多个核的cpu上运行
Go:通过高效的调度充分发挥多核优势
协程:用户态、轻量级线程,栈KB级别
线程:程序执行的最小单位,共享进程数据空间,内核态,线程跑多个协程,栈MB级别
进程:资源分布的最小单位,有自己的独立地址空间
go+函数,创建协程运行。
time.sleep(time.Second):为了协程完成之前线程不退出。
go:提倡通信共享内存
Channel: make(chan 元素类型,[缓冲大小])
无缓冲通道:make(chan int)(同步通道)
有缓冲通道:make(chan int,2)
示例:A子协程发送0-9;B子协程计算输入数字平方;主协程输出最后结果
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()
}
1.4 并发安全 Lock:五个协程并发执行对比
package main
import (
"sync"
"time"
)
var (
x int64
lock sync.Mutex
)
func addWithLock() {
for i := 0; i < 2000; i++ {
lock.Lock()
x += 1
lock.Unlock()
}
}
func addWithOutLock() {
for i := 0; i < 2000; i++ {
x += 1
}
}
func Add() {
x = 0
for i := 0; i < 5; i++ {
go addWithOutLock()
}
time.Sleep(time.Second)
println("WithoutLock", x)
x = 0
for i := 0; i < 5; i++ {
go addWithLock()
}
time.Sleep(time.Second)
println("WithLock", x)
}
func main() {
Add()
}
1.5 wait group
package main
import (
"fmt"
"sync"
)
func hello(i int) {
println("hello goroutine: " + fmt.Sprint(i))
}
func ManyGowait() {
var wg sync.WaitGroup
wg.Add(5)
for i := 0; i < 5; i++ {
go func(j int) {
defer wg.Done()//减1
hello(j)
}(i)
}
wg.Wait()
}
func main() {
ManyGowait()
}
02 依赖管理
Go Vendor 通过每个项目引入一份依赖副本,解决了多个项目需要同一个package依赖的冲突问题 弊端:无法控制依赖版本
Go Module
go.mod/go.get
依赖管理三要素:
1.配置文件,描述依赖 go.mod
2.中心仓库管理依赖库 Proxy
3.本地工具 go get/mod
依赖配置:选择最低的兼容版本
依赖分发-Proxy
GOPROXY = "proxy1.cn,https://proxy2.cn,…"
go get example.org/okg
go mod:
init 初始化go.mod文件
download 下载模块到本地缓存
tidy 增加需要的依赖,删除不需要的依赖
总结: 前面3章理解较清晰 最后项目老师讲的太急 没太听懂。