Created
September 9, 2020 01:39
-
-
Save x893675/05d088aaaa4f4d9e8f132b077af73b2a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"runtime" | |
"sync" | |
) | |
func main() { | |
testA() | |
//testB() | |
//testC() | |
} | |
// 由于闭包只是绑定到这个value变量上,并没有被保存到goroutine栈中, | |
// 所以以上代码极有可能运行的结构都输出为切片的最后一个元素。 | |
// 因为这样写会导致for循环结束后才执行goroutine多线程操作,这时候value值只指向了最后一个元素。 | |
func testA() { | |
var wg sync.WaitGroup | |
for i := 1; i < 10; i++ { | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
fmt.Println(i) | |
}() | |
} | |
wg.Wait() | |
} | |
// 乱序打印 | |
func testB() { | |
var wg sync.WaitGroup | |
for i := 1; i < 10; i++ { | |
wg.Add(1) | |
go func(value int) { | |
defer wg.Done() | |
fmt.Println(value) | |
}(i) | |
} | |
wg.Wait() | |
} | |
// 固定输出 9,1,2,3,4,5,6,7,8 | |
// runtime2.go 中关于 p 的定义: 其中 runnext 指针决定了下一个要运行的 g,根据英文的注释大致意思是说: | |
// | |
// 1 . 如果 runnext 不为空且是就绪的,那么应该优先运行该 runnext 指向的 g 而不是运行队列中到达运行时间的 g。 | |
// 2 . 此时要被运行的 g 将继承当前 g 剩余的时间片继续执行。 | |
// 3 . 之所以这样做是为了消除将最后的 g 添加到队列末尾导致的潜在的调度延迟。 | |
// 所以当设置 runtime.GOMAXPROCS(1) 时,此时只有一个 P,创建的 g 依次加入 P, 当最后一个即 i==9 时, | |
// 加入的最后 一个 g 将会继承当前主 goroutinue 的剩余时间片继续执行,所以会先输出 9, 之后再依次执行 P 队列中其它的 g。 | |
func testC() { | |
runtime.GOMAXPROCS(1) | |
var wg sync.WaitGroup | |
for i := 1; i < 10; i++ { | |
wg.Add(1) | |
go func(value int) { | |
defer wg.Done() | |
fmt.Println(value) | |
}(i) | |
} | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment