以下四种情形下,goroutine 可能会发生调度,但也并不一定会发生,只是说 Go scheduler 有机会进行调度。
情形 | 说明 |
---|---|
使用关键字 go |
Go语句执行时,当程序运行到一个 Go 语句时,会创建一个新的 Goroutine 并将其放入可运行队列中,等待调度器选择一个合适的系统线程(M)来执行。 |
GC | 由于进行 GC 的 goroutine 也需要在 M 上运行,因此肯定会发生调度。当然,Go scheduler 还会做很多其他的调度,例如调度不涉及堆访问的 goroutine 来运行。GC 不管栈上的内存,只会回收堆上的内存 |
系统调用 | 当 goroutine 进行系统调用时,文件 I/O等操作时会阻塞 M,所以它会被调度走,同时一个新的 goroutine 会被调度上来 |
内存同步访问 | atomic,mutex,channel 操作等会使 goroutine 阻塞,因此会被调度走。当一个 Goroutine 尝试获取一个已经被其他 Gor |