GO例程中缓冲通道范围的输出中断

时间:2018-12-12 22:44:11

标签: go channel goroutine

当使用缓冲通道时,为什么像下面这样的GO例程会以随机顺序输出字节序列?

这是用于复制越野车行为的代码,其中data.csv是简单的CSV,包含1000行随机数据(每行大约100个字节)和标题行(总共1001行)。

package main

import (
    "bufio"
    "os"
    "time"
)

func main() {

    var channelLength = 10000
    var channel = make(chan []byte, channelLength)

    go func() {
        for c := range channel {
            println(string(c))
        }
    }()

    file, _ := os.Open("./data.csv")
    scanner := bufio.NewScanner(file)

    for scanner.Scan() {
        channel <- scanner.Bytes()
    }

    <-time.After(time.Second * time.Duration(3600))

}

以下是输出的前6行,以举例说明“中断输出”的含义:

979,C
tharine,Vero,cveror6@blinklist.com,Female,133.153.12.53
980,Mauriz
a,Ilett,milettr7@theguardian.com,Female,226.123.252.118
981
Sher,De Laci,sdelacir8@nps.gov,Female,137.207.30.217
[...]

另一方面,如果channelLength = 0,则代码可以平稳运行,因此对于未缓冲的通道(前6行,再次):

id,first_name,last_name,email,gender,ip_address
1,Hebert,Edgecumbe,hedgecumbe0@apple.com,Male,108.84.217.38
2,Minor,Lakes,mlakes1@marriott.com,Male,231.185.189.39
3,Faye,Spurdens,fspurdens2@oakley.com,Female,80.173.161.81
4,Kris,Proppers,kproppers3@gmpg.org,Male,10.80.182.51
5,Bronnie,Branchet,bbranchet4@squarespace.com,Male,118.117.0.5
[...]

数据是随机生成的。

1 个答案:

答案 0 :(得分:7)

buffer.Scanner文档中:

  

基础数组可能指向后续调用Scan会覆盖的数据

您将围绕在通道上传递的切片的使用进行数据竞赛。您需要复制要发送的数据。在此示例中,最简单的方法是使用string而不是[]byte,然后调用scanner.Text