0、GPM模型
1、默认地, Go所有的goroutines只能在一个线程里跑 ,除非告诉Go我们允许同时最多使用多个核,或者主动让出CPU时间,使goroutine可以抢占式的执行
2、如果当前goroutine不发生阻塞,它是不会让出CPU给其他goroutine的, 所以程序会是一个一个goroutine进行(但是CPU的调度会是线程切换)
3、无缓冲的信道在取消息和存消息的时候都会挂起当前的goroutine,除非另一端已经准备好
p := make(chan int); p <- 2; go func() { v := <- p; fmt.Println(v); }() // 这种执行会产生错误,死锁,即:fatal error: all goroutines are asleep - deadlock! p := make(chan int); go func() { v := <- p; fmt.Println(v); }() p <- 2; // 这种可以执行 // 我觉得是因为这个 channel 是无缓冲的,必须即存即取,如果只存不取或者只取不存,都会产生阻塞,除非另一方已经准备好。。。 // 第一种不行的原因是赋值给chan时,主routine就已经被阻塞并挂起了,来不及执行下面的代码,导致子routine无法生成并执行,这样程序就会阻塞并导致死锁; // 第二种是因为已经生成了子routine才去赋值chan,这样主routine挂起了只要等待子routine取出值就行
4、非缓冲信道上如果发生了流入无流出,或者流出无流入,也就导致了死锁。或者这样理解 Go启动的所有goroutine里的非缓冲信道一定要一个协程里存数据,一个协程里取数据,要成对才行 。
5、无缓冲信道并不存储数据,只负责数据的流通
6、定义一个redis连接对象,作为参数丢进协程执行会报错