理论概念基础
理解高并发
线程与协程
线程:内核态,(栈MB级别)
协程:用户态,相当于轻量级的线程。内存更小(栈KB级别)
协程和线程能干什么?
答案:
协程:协程是轻量级的,特别适合处理I/O密集型任务(例如网络请求、数据库查询)。
协程在遇到I/O阻塞时会自动让出控制权,不会消耗系统资源,从而提升并发效率。
Go中的goroutine即是协程的实现方式,启动一个goroutine仅需极小的资源开销,通常只需几KB内存。
线程:线程由操作系统调度,适合处理计算密集型任务(例如加密、图像处理、复杂运算)。
尽管线程的切换比协程慢,但多线程仍然适用于无法避免的密集计算需求,并利用多核CPU资源来提升性能。
线程适合那些任务周期长、计算量大,且无法在中途切换或让出的任务。
根据以上介绍可知:协程是更快的也是更轻量的,如何开启一个协程?
//使用go关键字,如
go func(j int){
hello(j)
}
通过通信实现共享内存和通过共享内存实现通信是什么意思
答案:
通过通信实现共享内存:这是指Go中推荐的方式。通过`Channel`传递数据,实现协程间的同步或数据交换,不直接访问共享变量,避免竞态条件。
通过共享内存实现通信:则是指在多线程中使用共享变量,并通过`sync`包中的锁机制控制访问,确保并发安全。
协程之间的通信 Channel(通过通信来实现共享内存)
//创建Channel
make(chan 数据类型, [缓冲大小])
1.无缓冲通道 make(chan int)
2.有缓冲通道 make(chan int,2)
无缓冲通道会导致g1和g2同步化,解决这一问题的方法通道
g1和g2同步化会发生什么?
答案:
当g1和g2通过无缓冲通道同步时,若g1发送数据,g2必须准备接收,g1才能继续运行。否则g1会阻塞,直到g2准备好。这种同步会强制两者“锁步”运行
sync
并发安全lock (共享内存实现通信)
个人理解:当需要对同一内存空间进行操作时,会出现同一时间多个协程访问和修改相同的内存空间(竞态条件),lock类似于当此协程执行的时候,锁定当前内存空间,不允许其他协程对这个内存空间执行操作
//如何使用?
var lock sync.Mutex // 定义lock操作对象
//当需要使用时
lock.Lock() // 锁定
//执行操作
lock.Unlock() //解锁
WaitGroup
//初始化
var wg sync.WaitGroup
//添加计时器 waitgroup实例化对象- wg.add(delta int) //add方法,并传入参数
wq.Add(5)
//关闭计时器(数量级为1)每次执行关闭一个计时器
wg.Done()
//阻塞协程直至计时器结束
wg.Wait()
依赖管理
Go Module
依赖管理三要素
配置文件,描述依赖 go.mod
中心仓库管理依赖库 Proxy
本地工具 go get/mod
go.mod
标明依赖的包以及版本
Proxy
缓存依赖的版本的中间站点
go get/mod
获取proxy的包的内容