Go 无缓冲信道

Go 无缓冲信道,go,Go,我正在做巡回演出: 这是我的代码: package main import ( "code.google.com/p/go-tour/tree" "fmt" ) // Walk walks the tree t sending all values // from the tree to the channel ch. func Walk(t *tree.Tree, ch chan int) { var makeWalk func(t *tree.Tree, ch c

我正在做巡回演出: 这是我的代码:

package main

import (
    "code.google.com/p/go-tour/tree"
    "fmt"
)

// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
    var makeWalk func(t *tree.Tree, ch chan int)

    makeWalk = func(t *tree.Tree, ch chan int) {
        if t.Left != nil {
            makeWalk(t.Left, ch)

        }
        fmt.Println("-->", t.Value)
        ch <- t.Value
        fmt.Println("continue here")
        if t.Right != nil {
            makeWalk(t.Right, ch)
        }
    }
    makeWalk(t, ch)
    close(ch)
}

// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
 //   var ch_l chan int = make(chan int)
 // var ch_r chan int = make(chan int)
    return false
}

func main() {
    ch := make(chan int)
    go Walk(tree.New(1), ch)    
    for i := range(ch) {
        fmt.Println(i)
    }
}
据我所知,通道在传递值时会阻塞。我希望看到这样的输出:

--> 1
1
continue here
--> 2
2
continue here
...
--> 10
10
continue here

通道未缓冲,是否缓冲了
fmt.Println
?这里发生了什么?:)

你提到
fmt.Println
是正确的。通道读取和写入不是调度程序切换到另一个goroutine的唯一时间。阻塞系统调用也可以触发上下文切换

从:

当协程阻塞时,例如通过调用阻塞系统调用, 运行时会自动移动同一服务器上的其他协程 操作系统线程到另一个可运行线程,这样它们就不会 被封锁了


fmt.Println
最终将调用一个阻塞系统调用(
write()
),这就是您看到这种行为的原因。

没有同步机制,因此主函数从通道接收,现在goroutine可以在通道上发送并前进,但有时在调用Println之前会发生这种情况。所以你得到了这种“随机”行为。如果我理解你-通道阻塞正确,但是发送/接收比
main
中的
Println
快?顺便问一下,同步的正确方法是什么?谢谢,这很有意义。:)
--> 1
1
continue here
--> 2
2
continue here
...
--> 10
10
continue here