1. 首页
  2. 主题
  3. Go问与答

go语言实战中有段代码不明白,请问哪位帮忙给看一下,多谢

darren_lou · · 3223 次点击
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)情况下实际是假并行,需要切换时间片,而goroutine一般会在阻塞时才进行切换。 这个例子中的两个goroutine都没有阻塞,所以都是全部大写字母或全部小写字母打印完,才切换到别的goroutine。可以在两个goroutine的循环中都加入time.Sleep(1),就会出现大小写字母交替打印(但不是完全一一交替)。而且这种情况下,main goroutine如果不阻塞也会直接执行完,进程就停了。 至于先打印大写字母的原因,我想应该是和goroutine的队列和栈类似吧,先进后出,后进先出。
#4
更多评论
这里应该是单核状态下调度器算法决定的,我一开始以为是defer先进后出的机制造成的结果,后来试了一下for循环输出0-9,得到的结果是9012345678,所以排除defer入栈的可能,目前以我的理解是这样的,你可以试试你单核时候打印0-9是不是和我一样的结果
#1
go内部有一套协程调度机制,类似cpu线程上下文切换,每个线程会给一个固定的时间片来执行,时间片结束之后会暂停这个线程并将上下文切换到下一个线程。这里的意思可能是说这个goroutine在时间片之内就执行完成了,并没有发生上下文切换,而且runtime.GOMAXPROCS(1)是设置最大并行数,所以相当于是单核,不存在多个goroutine并行。 那么问题来了,为什么始终会先打印大写,坐等大佬
#2

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中