Goroutine
- Goroutine
并发x并行x串行
并发: 并发是一个核运行多线程程序,说人话就是一个程序分为好多个子程序,然后一个人干,这个人一会干这个一会干那个,类似于ABCBCABCA….这样子干,因为计算机运行速度很快,就给人一种“多线程”的感觉,一个人在同时做很多事情
并行: 并行就是多核运行多线程程序,说人话就是多个人一起干多个程序
串行: 多线程程序中,要先干完线程A,再干线程B……
并发就是一个人同时吃三个馒头,并行是三个人吃三个馒头
在Go实战中描述
- 并行是让不同的代码片段在不同的物理处理器上执行,关键是同时做很多事情
- 并发是指同时管理很多事情,这些事情可能做了一半就被暂停就去做别的事情了
一般来说,我们总觉得并行更好,因为他多步进行,但是事实上操作系统上的资源总是少得可怜,从”使用较少的资源做更多的事情”的哲学出发,并发只使用了很少的资源,却能够管理很多事情,注意这里是管理。
线程和协程
线程: 内核态,线程跑多个协程,栈MB级别
协程: 用户态,轻量级线程,栈KB级别
没啥好理解的,反正协程就是轻量
1 | func hello(i int) { |
1 | print: |
再次理解一下
进程 = ==内存== + ==文件和设备的句柄== + ==CPU调度器==(线程)
每个进程至少包含一个线程,每个进程初始线程被称作主线程,因此我们常常会使用sync.wait来使主goroutine来等待其他协程的完成,如果主goroutine先关闭,其他协程也会关闭
进程是一个大的空间,包含程序执行的各种资源
线程是一个执行的空间
多线程——多CPU
而一个线程上有一个==逻辑处理器==(Go特有),而这个逻辑处理器处理的就是协程
我们可以把这个逻辑处理器看作一个队列,而开启一些goroutine就是让这些goroutine入队,逻辑的含义就是系统会通过一些算法使得多个goroutine按顺序运行,同时需要明白的是:运行顺序并不是goroutineA,goroutineB… 而是会在某个goroutine运行到某个阶段去运行其他goroutine,具体运行到什么阶段 就是算法的事情了
竞争状态
如果多个或者多个 goroutine 在没有互相同步的情况下,访问某个共享的资源,并试图同时读和写这个资源,就会处于相互竞争的状态。
这个状态我们可以从Mysql的幻读等缺陷可以类比
因此我们需要锁住共享资源
sync.Mutex
互斥锁,互斥锁用于在代码上创建一个临界区,保证同一时间只有一个goroutine可以执行这个临界区的代码
1 | var ( |
1 | print: |
1 | func main(){ |
==LoadInt64== 和 ==StoreInt64== 提供了读和写的方式,可以试试
time.S
leep()太呆板了,换个高级的sync.WaitGroup
1 | var ( |
1 | print: |
Channel
请跳转到Channel那篇笔记中