对于go的用法不是很明白

zhoujie13 · 2019-09-08 15:58:32 · 1217 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2019-09-08 15:58:32 的主题,其中的信息可能已经有所发展或是发生改变。

package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

官网的例子,为什么先执行fibonacci函数后再执行go


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1217 次点击  
加入收藏 微博
7 回复  |  直到 2019-09-09 17:18:48
polaris
polaris · #1 · 6年之前

这涉及到调度的问题

bin44702513
bin44702513 · #2 · 6年之前

个人理解是,main是入口函数,在这里面的代码会比其他并发程序更快的执行

kuangyuansheng
kuangyuansheng · #3 · 6年之前

我理解是c是没有缓冲的通道, c要先写,才能读. 所有go func里面先是堵塞的, 然后fibonacci里面select c <- x, 然后go func才能printf

zdf123456
zdf123456 · #4 · 6年之前

通道创建带参数且为0为无缓冲阻塞读写,所以先执行到fibonacci函数,其实是先执行到Go但是被阻塞了,不带参数默认是等价于参数为0

zhoujie13
zhoujie13 · #5 · 6年之前
kuangyuanshengkuangyuansheng #3 回复

我理解是c是没有缓冲的通道, c要先写,才能读. 所有go func里面先是堵塞的, 然后fibonacci里面select c <- x, 然后go func才能printf

阻塞的意思是在没有执行条件下先跳过,有条件执行了再回头执行吗

Liaomessi
Liaomessi · #6 · 6年之前

go中的main函数也是一个携程,个人认为是先进入的匿名函数还是fibonacci函数是不一定的。无缓存的通道,在通道里没有写入值的时候会阻塞,你的匿名函数中读取一个没有写入值的c通道会堵塞,所以不管是先执行的匿名函数还是主函数中的fibonacci函数,最终都会等待fibonacci函数执行。

shi_yi_fei
shi_yi_fei · #7 · 6年之前

因为select语句导致的,select 语句中的quit只是读取,所以需要其他协程先写入quit信道中, 如果你想调顺序的话,在main()中 fibonacci语句前 加入defer也是可以的。 如果不想让程序报错的话,可以在select语句中加入 default项

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传