1.设置runtime.GOMAXPROCS(1)
func TestOneGoMaxProcs(n int) {
runtime.GOMAXPROCS(1)
wg := &sync.WaitGroup{}
wg.Add(n)
for i := 0; i < n; i++ {
go func(i int) {
fmt.Printf("%d,", i)
wg.Done()
}(i)
}
wg.Wait()
}
1.1 遍历50每个1协程,打印结果及原因
打印结果: 先打印最后一个数字49,然后顺序打印其它数字。
// p对应结构体,位于runtime/runtime2.go
type p struct{
m muintptr // 指向它服务的那个线程
runqhead // 本地队列的头
runqtail // 本地队列的尾
runq [256]guintptr // 256长度指针,每个指针指向一个g
runnext guintptr // 指向下一个可用的指针
}
原因:因为新创建的协程会进入 _p_.runnext,而之前的在_p_.runnext中的协程则会被移动到_p_.runq队列中,所以49先打印了之后才是按照大小依次打印。
1.2 遍历300每个1协程,打印结果及原因
打印结果: 先打印最后一个数字,部分随机,局部有序打印其它数字。
原因:本地队列runq最大256,超出则会存全局队列
参考链接
2 使用多个协程并发的按照顺序打印
2.1 交替打印奇偶数
runtime.GOMAXPROCS(1) // 可同时使用cpu核数1
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
if i%2 != 0 {
fmt.Println(i)
}
runtime.Gosched() // 让出cpu
}
}()
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
if i%2 == 0 {
fmt.Println(i)
}
runtime.Gosched()
}
}()
wg.Wait()