go的并发编程
并发两个goroutine中同时操作了 一个共享资源,引发的竞争行为
1. 使用原子函数
2. 使用互斥锁
3. 使用通道
并发和并行
并发是同一个时间段内做很多事(同时发生),比如一个线程管理多个goroutine,一个时间段内会执行多个goroutine, 这个时间段内,这些任务可能同时执行,也可能不是同时执行(所以并发在概念上 包括“并行”)
并行是同一时刻做很多事(同一时刻),多个线程管理多个gotoutine
多线程程序在单核上运行,就是并发;多线程程序在多核上运行,就是并行。
了解并发模型之前(了解goroutine 和 线程的区别)
Goroutine:是建立在线程之上的轻量级的抽象。它允许我们以非常低的代价在同一个地址空间中并行地执行多个函数或者方法。相比于线程,它的创建和销毁的代价要小很多,并且它的调度是独立于线程的
- goroutine与线程区别
- 内存消耗更小
Goroutine所需要的内存通常只有2kb,而线程则需要1Mb(500倍) - 创建和销毁消耗小
Goroutine的创建和销毁都是自己管理,
线程的创建和销毁是 需要内核管理的,消耗更大 - 上下文切换
线程是抢占式的,一段时间内线程执行完成,其他线程抢占cpu,需要保存很多线程状态,用来再次执行的时候恢复线程,
goroutine 的调度是协同式,不需要切入内核,只需要保存少量的寄存器信息需要保存和恢复
go 的CSP 并发模型
并发的两种形式:
“不要使用共享内存通信,要使用通信来共享内存”
- 多线程共享内存
普通的线程并发模型,线程的通信使用共享内存的方式进行,在访问共享数据(例如数组,Map,或者某个结构体或对象的时候)使用锁(互斥锁,自旋锁,读写锁,原子锁)来访问。 - csp模型,使用通信来共享内存
通过goroutine和channel来通信-
goroutine 是go的 并发执行单位,生成一个goroutine
go func()
-
channel 是goroutine之间的通信机制,就是goroutine之间的管道
ch:= make(chan type)
-
并发模型代码