func main() {
runtime.GOMAXPROCS(1)
var wg sync.WaitGroup
wg.Add(2)
fmt.Println("Start Goroutines")
go func(){
defer wg.Done()
for count := 0; count < 3; count++{
for char := 'a'; char < 'a' + 26; char++{
fmt.Printf("%c ", char)
}
}
}()
go func(){
defer wg.Done()
for count := 0; count < 3; count++{
for char := 'A'; char < 'A' + 26; char++{
fmt.Printf("%c ", char)
}
}
}()
fmt.Println("Waiting To Finish")
wg.Wait()
fmt.Println("\nTerminating Program")
}
输出结果为
Start Goroutines
Waiting To Finish
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z
Terminating Program
不明白为什么先输出大写字母,书上有一段解释,看了之后依然一头雾水,以下是书上的解释。
第一个goroutine 完成所有显示需要花时间太短了,以至于在调度器切换到第二个goroutine
之前,就完成了所有任务。这也是为什么会看到先输出了所有的大写字母,之后才输出小写字母。
哪位能解释一下什么叫“第一个goroutine 完成所有显示需要花时间太短了,以至于在调度器切换到第二个goroutine
之前,就完成了所有任务”?这句完全不明白在说什么呀?
即使runtime.GOMAXPROCS(1)设置为1时,goroutine也会并行,叫抢占式并发,go汇编在第个函数的入口都加入了一个扩栈汇编,此汇编会引起栈的切换,发现在两个时机
1)调用的函数发生栈扩展
2)时间片到了
你例子中没有发切换时时间片还没有到,你把count循环搞成30000就可以看到大小写轮流出现了
#6
更多评论
这里应该是单核状态下调度器算法决定的,我一开始以为是defer先进后出的机制造成的结果,后来试了一下for循环输出0-9,得到的结果是9012345678,所以排除defer入栈的可能,目前以我的理解是这样的,你可以试试你单核时候打印0-9是不是和我一样的结果
#1
go内部有一套协程调度机制,类似cpu线程上下文切换,每个线程会给一个固定的时间片来执行,时间片结束之后会暂停这个线程并将上下文切换到下一个线程。这里的意思可能是说这个goroutine在时间片之内就执行完成了,并没有发生上下文切换,而且runtime.GOMAXPROCS(1)是设置最大并行数,所以相当于是单核,不存在多个goroutine并行。
那么问题来了,为什么始终会先打印大写,坐等大佬
#2