#golang GMP调度

对于Go中的阻塞需要了解一下有哪些场景会发生,可以参考上面提到的GPM文章。 常见的阻塞一般发生在像网络请求、系统调用进行磁盘IO操作、执行Sleep函数等,而针对每一种阻塞的处理方式也不一样。 如果是网络导致的阻塞的话,则直接将G切换到网络轮询器NetPoller继续执行, 为PM重新调度过来一个新的G继续执行,等网络请求完成后,再将G追加到LRQ的队列尾部等待再次执行。 而对于系统调用产生的IO阻塞这种情况,则 Go Seched 则直接将M和G同时切换出去,并保持MG继续执行IO操作,出让出来的P再分配一个新的MG继续执行。等原来IO操作完成后,将原来的G放入LRQ队列,等待P的再次执行,而原来的M放在一旁等待被重复调用使用。可以看到原来的G和M关系到此结束了,下次与G执行的M不一定是原来的M了, 所以G再次执行就需要知道运行状态,堆栈之类的信息,而这些正是存储在G的结构体中了。