为循环

时间:2018-02-14 16:30:45

标签: go concurrency channels

我遇到了一种奇怪的行为。我正在使用缓冲通道,当使用大缓冲区时,整个程序执行将会阻塞。在以下代码段中:

package main

import (
    "fmt"
)

func main() {
    choke := make(chan string, 150000)

    go func() {
        for i := 0; i < 10000000; i++ {
            choke <- string(i)
            fmt.Println("i=", i)
        }
    }()

    for {
        //fmt.Println(len(choke))
        if len(choke) >= 150000 {
            fmt.Println("Full")
        }
    }
}

我的程序在~96000次迭代时阻止,并且永远不会到达&#34; Full&#34;打印,除非我在评估之前打印出len(choke)。这可能是由fmt.Println提供的延迟造成的,因为这个问题也可以解决问题&#34;添加一个小time.Sleep

有人可以解释这种行为的原因吗?

1 个答案:

答案 0 :(得分:5)

这种情况正在发生,因为你的goroutine永远不会执行。 &#34; for&#34;循环你在goroutine之外是一个没有任何阻塞操作的紧密循环,这意味着它获得了所有的调度程序时间。因此,您创建的goroutine永远不会被安排执行。

当你有print语句时它会起作用,因为这是一个阻塞操作(I / O),它导致Go调度程序切换到你创建的goroutine。