- 并发vs并行
1. 并发:多线程程序在 单核 上运行,同一时间只会执行一个线程。
并发一般都是被内核通过时间片或者中断来控制的
一旦遇到IO阻塞或者时间片用完,就会转移线程的使用权。
2. 并行:多线程程序在 多核 上运行,在不同的cpu核心上同时执行多个线程。
- go协程
1. 有独立的栈空间
2. 共享程序堆空间
3. 调度由用户控制
4. 协程是轻量的线程
-
go xxx开启协程,主线程退出(main方法执行完),协程没有执行完也会退出。
-
设置执行的cpu核心数(虚拟)
1) golang默认使用系统相同的cpu核心数
2) runtime.GOMAXPROCS 可以设置核心数。
3) 并行比较适合cpu计算密集型。如果IO密集型使用多核反而会增加cpu切换的成本。
4) 当多个go协程发生资源的争夺(IO、单线程操作)时,切换cpu,导致效率过低
5) 多个cpu核心争夺同个变量、导致报错:concurrent map writes
这时候,使用单核,效率反而更高 runtime.GOMAXPROCS(1)
- channel
1. channel本质是一个队列(先进先出)
2. 多个goroutine时,不需要加锁(线程安全)
3. channel是有类型的,一个channel只能放同种类型数据
4.
- close(channel) 关闭一个管道,如果不关闭则读取channel时会出现deadlock错误
- deadlock的原因:
1. 写入管道不关闭,读取超过管道边界
2. 写入管道不读取
3.
- 通过select读取管道的数据,可以不关闭管道