并发:逻辑上具备同时处理多个任务的能力
并行:物理上在同一时刻执行多个并发任务
单线程的用协程做并发:协程在单个线程上通过主动切换来实现多个任务并发(协程上运行的多个任务本质上是依旧串行,加上可控自主调度,所以并不需要做到同步处理)
用多线程来实现分布式和负载均衡,减轻单进程垃圾回收压力;用线程抢夺更多的处理器资源;用协程来提高处理器时间片利用率
关键字go并非执行并发操作,而是创建一个并发任务单元,新建任务被放置在系统队列中,等待调度器安排合适系统线程去获取执行权。当前流程不会阻塞,不会等待改任务启动,且运行时也不保证并发任务的执行次序
runtime.Gosched:释放线程去执行其他任务,当前任务被放回队列,等待下次调度时恢复执行(该函数很少被使用,因为运行时会主动向长时间运行(10ms)的任务发出抢占调度)
panic:是用来表示非常严重的不可恢复的错误(panic的作用就是平时异常,不过go没有try..catch,panic一般就会导致程序挂掉,除非recover),panic会在defer执行完后向上传递
recover:捕获panic的异常信息,后续流程可以继续走(如果没有recover捕获,全流程将会结束)
Goexit:可以立即终止整个调用堆栈,会执行延迟调用
os.Exit可以终止进程,但不会执行延迟调用
GO鼓励使用CSP通道,以通信来代替内存共享,实现并发安全(GO允许全局变量、指针、引用类型这些非安全内存共享操作)
通道:同步模式下,发送和接受双方配对,然后直接复制数据给对方。如配对失败,则置入等待队列,直到另一方出现后才会被唤醒。异步模式抢夺的则是数据缓冲槽。发送方要求有空槽可供写入,而接受方则要求有缓存数据可读。需求不符时,同样加入等待队列,直到另一方写入数据或者腾出空槽后被唤醒
通道(goroutine之间的内存共享)
无缓冲的通道(channel),写完后就会阻塞,这种情况只有其他协程中有对应的读操作才会解除阻塞。而带缓冲的通道在max+1才会阻塞
无缓冲:make(chan int);有缓冲:make(chan int,1)
time.Tick():做时间间隔,可用在定时任务(用于channel)
time.after():到时间发生的事情
通道和锁的差别:通道倾向于解决逻辑层次的并发处理架构,而锁则用来保护局部范围内的数据安全
有疑问加站长微信联系(非本文作者)