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连接对象,作为参数丢进协程执行会报错

05-11 17:54