考虑以下应用程序,旨在衡量goroutine
创建延迟。假设我们正在运行GOMAXPROCS=2
。
package main
import "fmt"
import "time"
const numRuns = 10000
type timeRecord struct{
Ts time.Time
Msg string
}
var timeStamps []timeRecord
func threadMain(done chan bool) {
timeStamps = append(timeStamps, timeRecord{time.Now(), "Inside thread"})
done <- true
}
func main() {
timeStamps = make([]timeRecord, 0, numRuns*2)
done := make(chan bool)
dummy := 0
for i := 0; i < numRuns; i++ {
timeStamps = append(timeStamps, timeRecord{time.Now(), "Before creation"})
go threadMain(done)
<-done
}
// Regularize
regularizedTime := make([]time.Duration, numRuns*2)
for i := 0; i < len(timeStamps) ; i++ {
regularizedTime[i] = timeStamps[i].Ts.Sub(timeStamps[0].Ts)
}
// Fake timetraced
fmt.Printf("%6d ns (+%6d ns): %s\n", 0, 0, timeStamps[0].Msg)
for i := 1; i < len(timeStamps) ; i++ {
fmt.Printf("%8d ns (+%6d ns): %s\n", regularizedTime[i], (regularizedTime[i] - regularizedTime[i-1]).Nanoseconds(), timeStamps[i].Msg)
}
}
在我的服务器上,这始终从Before creation
到Inside thread
大致输出中值 260 ns delta 。现在考虑主要方法的以下变化。
timeStamps = make([]timeRecord, 0, numRuns*2)
done := make(chan bool)
dummy := 0
for i := 0; i < numRuns; i++ {
timeStamps = append(timeStamps, timeRecord{time.Now(), "Before creation"})
go threadMain(done)
for j := 0; j < 1000; j++ {
dummy += j
}
<-done
}
在此变化下,相同的时间delta大致 890 ns 。
显然,确切的数字是机器特定的,但数字之间的差异很奇怪。从逻辑上讲,如果我在&#34;之前测量&#34;在创建之前&#34;在&#34;内部线程&#34;中,在go
语句之后添加额外的逻辑似乎不应该增加那个时间,但确实如此。
有没有人知道为什么在预期的位置没有发生时间增加?
答案 0 :(得分:0)
Go调度程序是合作的。它可以仅在程序的某些点(例如函数调用,读/写通道等)将当前goroutine切换到另一个。我希望您观察到的差异是由于goroutine在以后启动(之后)添加for循环)。