You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/posts/技术分享/调度模型/go-schedule.md
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -460,7 +460,7 @@ top: // 循环起点
460
460
461
461
### 系统调用
462
462
463
-
我们经常会说在陷入阻塞系统调用的时候,这个 m 会和 p 立即解绑,会去另外找一个 m 去执行,而非阻塞的系统调用虽然也会解绑,但是这个 m 会记住这个 p,等从系统调用返回之后,会优先去获取这个 p,刘丹冰的《深入理解Go语言》也正是这么写的,但是这个说法并不算准确:
463
+
我们经常会说在陷入阻塞系统调用的时候,这个 m 会和 p 立即解绑,会去另外找一个 m 去执行,而非阻塞的系统调用虽然也会解绑,但是这个 m 会记住这个 p,等从系统调用返回之后,会优先去获取这个 p,刘丹冰的《深入理解Go语言》也正是这么写的,但是这个说法(阻塞和非阻塞)并不算准确:
464
464
```go
465
465
funcreentersyscall(pc, sp, bpuintptr) {
466
466
...
@@ -534,9 +534,11 @@ if s == _Psyscall {
534
534
```
535
535
虽然对于阻塞和非阻塞并没有明确的规定,但是我觉得这里的说法还是可以再优化一下,阻塞还是非阻塞,要不要给这个 P 安排新的 M 完全取决于系统监控以及当时的资源紧张情况。
536
536
537
+
当然,在退出执行系统调用的时候,会执行 `exitsyscall` 这个函数,此时会优先去获取原来的 p,即陷入系统调用之前记录的 `oldp`,如果这个 p 已经转而去执行其他 m 了,那么就会从空闲的 p 中找一个来执行这个 m,如果没有任何能够执行这个 m 的 p,那么就会将这个 g 放入全局的运行队列,而这个 m 则通过 `stopm` 进入到空闲的 m 列表,并陷入睡眠。
0 commit comments