为了账号安全,请及时绑定邮箱和手机立即绑定

转到频道 - 我的代码看起来会覆盖频道但有效。

转到频道 - 我的代码看起来会覆盖频道但有效。

Go
慕运维8079593 2021-11-22 18:54:36
最近刚开始学习Go,学习Goroutine的时候很迷茫。这是我的代码。这打算同时完成3个过程。package mainimport (    "fmt"    "log"    "time")func wait1(c chan string) {    time.Sleep(1 * time.Second)    log.Print("waited 1 sec")    c <- "wait1 finished\n"}func wait2(c chan string) {    time.Sleep(2 * time.Second)    log.Print("waited 2 sec")    c <- "wait2 finished\n"}func wait3(c chan string) {    time.Sleep(3 * time.Second)    log.Print("waited 3 sec")    c <- "wait3 finished\n"}func main() {    c := make(chan string, 3)    log.Print("started")    go wait1(c)    go wait2(c)    go wait3(c)    w1, w2, w3 := <-c, <-c, <-c    log.Print("finished")    fmt.Println(w1, w2, w3)}对我来说,这部分看起来将不同的函数输入到名为 c 的同一个通道中,并尝试打印从 c 接收到的值。c := make(chan string, 3)log.Print("started")go wait1(c)go wait2(c)go wait3(c)w1, w2, w3 := <-c, <-c, <-clog.Print("finished")fmt.Println(w1, w2, w3)但是,如您所见,输出正是我所期望的。它同时处理 3 个函数并返回“完成”语句。2015/11/25 09:41:31 started2015/11/25 09:41:32 waited 1 sec2015/11/25 09:41:33 waited 2 sec2015/11/25 09:41:34 waited 3 sec2015/11/25 09:41:34 finishedwait1 finishedwait2 finishedwait3 finished为什么没有必要创建 3 个不同的通道,如 c1、c2、c3...?为什么即使我使用名为 c 的同一个通道,值也不会被覆盖?
查看完整描述

2 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

据我了解,您将渠道视为一个变量。一个可以保存一些值的变量。因此,如果有一些,value1而您又写了另一个,value2那么您基本上预计它们value1会消失。这是错误的。

尝试将通道视为缓冲区或优先级队列(有些人认为比较粗略)。通道有它的大小(你的第三个变量3),它告诉它可以同时有多少个值。一旦你在通道中放入了一些东西,你就可以将它看作是优先级等于完成这个 go-routine 所需时间的进程。

因此,在您的情况下,您将 3 个元素放入优先级队列中go wait(),然后使用w1, w2, w3 := <-c, <-c, <-c. 所以没有什么会被覆盖。


查看完整回答
反对 回复 2021-11-22
?
Qyouu

TA贡献1786条经验 获得超11个赞

无缓冲通道在发送数据之前同步。因此,在这种情况下,您<-c在分配行中的连续调用将阻塞,直到另一端的等待函数通过发送某些内容为止。

不过,Markus 提出了一个很好的观点,应该指出这w1, w2, w3 := <-c, <-c, <-c只是因为您已经错开了不同等待功能的等待时间。如果这些函数在通道上发送数据之前等待了任意时间,您将无法保证 w2 被分配给从 wait2 发送的结果。它只会被设置为通过通道发送的第二个值。


查看完整回答
反对 回复 2021-11-22
  • 2 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信