1 回答
TA贡献1772条经验 获得超8个赞
Go 编程语言规范中没有定义 Go 协程调度算法。它是未定义的,因此它依赖于实现和版本。Go 的当前实现使用协作调度方案。协作调度方案依赖于 goroutines 来执行不时让给调度程序的操作。调度程序代码在包运行时中。
该程序依赖于 Go 通道操作。
该程序还依赖于硬件(例如,CPU 数量)、操作系统和其他正在运行的程序。
您的代码不应期望来自 goroutine 调度的特定分布。
Go 1.4 默认为 GOMAXPROCS(1);对于 Go 1.5 及更高版本,它默认为 NumCPU()。
我已经修改了您的程序以修复错误(额外的等待语句)、显示诊断信息并在某些点让步给调度程序 (Gosched())。现在,该程序在 Go 1.6(开发技巧)、NumCPU() == 8、GOMAXPROCS(8) 和 Go Playround、Go 1.5.1、NumCPU() == 1、GOMAXPROCS(1) 上精确再现了您的结果。在紧密循环中的某些点而不是在其他点屈服于 goroutine 调度程序,是重现结果的关键。
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println(runtime.Version())
fmt.Println(runtime.NumCPU())
fmt.Println(runtime.GOMAXPROCS(0))
producer := make(chan int, 100)
wait := make(chan int, 100)
go func() {
for i := 0; i < 1000; i++ {
producer <- i
runtime.Gosched()
}
close(producer)
wait <- 1
}()
go func() {
count := 0
for _ = range producer {
count++
}
fmt.Printf("Consumer 1: %d\n", count)
wait <- 1
}()
go func() {
count := 0
for _ = range producer {
count++
runtime.Gosched()
}
fmt.Printf("Consumer 2: %d\n", count)
wait <- 1
}()
<-wait
<-wait
<-wait
}
随着屈服(Gosched()):
> go run yield.go
8
8
Consumer 1: 668
Consumer 2: 332
> go run yield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 2: 336
Consumer 1: 664
> go run yield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 2: 333
Consumer 1: 667
>
游乐场:https : //play.golang.org/p/griwLmsPDf
go1.5.1
1
1
Consumer 1: 674
Consumer 2: 326
go1.5.1
1
1
Consumer 1: 674
Consumer 2: 326
go1.5.1
1
1
Consumer 1: 674
Consumer 2: 326
为了比较,没有屈服:
> go run noyield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 1: 81
Consumer 2: 919
> go run noyield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 1: 123
Consumer 2: 877
> go run noyield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 1: 81
Consumer 2: 919
> go run noyield.go
devel +54b4b94 Sat Feb 6 23:33:23 2016 +0000
8
8
Consumer 2: 673
Consumer 1: 327
游乐场:https : //play.golang.org/p/2KV1B04VUJ
go1.5.1
1
1
Consumer 1: 100
Consumer 2: 900
go1.5.1
1
1
Consumer 1: 100
Consumer 2: 900
go1.5.1
1
1
Consumer 1: 100
Consumer 2: 900
- 1 回答
- 0 关注
- 142 浏览
添加回答
举报