V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
pengtoxen
V2EX  ›  问与答

向 channel 发送数据的问题

  •  
  •   pengtoxen · 2018-09-21 16:26:52 +08:00 · 1141 次点击
    这是一个创建于 2257 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在学习 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 内部调度的结果,不确定这个结论是否正确.

    3 条回复    2018-09-21 17:34:07 +08:00
    Aura7988
        1
    Aura7988  
       2018-09-21 17:31:09 +08:00
    我试了一下,也是轮流输出的。
    Aura7988
        2
    Aura7988  
       2018-09-21 17:33:33 +08:00
    但把休眠语句注释掉,就会无序输出了。不明白为啥。
    刚才不小心把一个回复弄成两个了。
    Ediacaran
        3
    Ediacaran  
       2018-09-21 17:34:07 +08:00
    我的认知是,调用 msg_chan <- 之后会执行一次调度,结果就是两个 goroutines 依次写入数据
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3321 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:22 · PVG 20:22 · LAX 04:22 · JFK 07:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.