向 channel 发送数据的问题

2018-09-21 16:26:52 +08:00
 pengtoxen

最近在学习 golang,对其中的 channel 有些不明白,希望有朋友可以解惑

package main

import (
	"fmt"
	"time"
)

func go1(msg_chan chan string) {
	for {
		msg_chan <- "go1"
	}
}
func go2(msg_chan chan string) {
	for {
		msg_chan <- "go2"
	}
}
func count(msg_chan chan string) {
	for {
		msg := <-msg_chan
		fmt.Println(msg)
		time.Sleep(time.Second * 1)
	}
}
func main() {
	var c chan string
	c = make(chan string)
	go go1(c)
	go go2(c)
	go count(c)
	var input string
	fmt.Scanln(&input)
}

运行后输出如下

go1
go2
go1
go2
go1
go2

可以看到 go1 和 go2 是交替输出的,我测试了多次,发现结果相同都是交替输出.

go1 函数和 go2 函数这两个是交替执行的吗?

在我目前的认知中,应该是 go1 和 go2 处于一个竞争关系,有可能 go1 发送了 2 个数据到 channel 后,待 main 函数把数据从 channel 中取出后,go2 才发送数据到 channel. 最后输出的结果应该是无序的.

然后结果却是有序的.不明白背后的机制是怎么样的.

ps: 有人说是 CPU 内部调度的结果,不确定这个结论是否正确.

1094 次点击
所在节点    问与答
3 条回复
Aura7988
2018-09-21 17:31:09 +08:00
我试了一下,也是轮流输出的。
Aura7988
2018-09-21 17:33:33 +08:00
但把休眠语句注释掉,就会无序输出了。不明白为啥。
刚才不小心把一个回复弄成两个了。
Ediacaran
2018-09-21 17:34:07 +08:00
我的认知是,调用 msg_chan <- 之后会执行一次调度,结果就是两个 goroutines 依次写入数据

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/491589

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX