go - GO 例程中缓冲通道范围的输出损坏
问题描述
为什么像下面这样的 GO 例程在使用缓冲通道时以随机顺序输出字节序列?
这是复制错误行为的代码,其中data.csv
是 1000 行随机数据(每行大约 100 个字节)加上标题行(总共 1001 行)的简单 CSV。
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
[...]
数据是随机生成的。
解决方案
从buffer.Scanner
文档:
底层数组可能指向将被后续调用 Scan 覆盖的数据
您围绕使用您通过通道传递的切片进行了数据竞赛。您需要复制要发送的数据。在这个例子中,这很容易通过使用 astring
而不是[]byte
, 并调用scanner.Text
推荐阅读
- javascript - 在平面列表中使用本地 img (React-Native)
- javascript - Chart JS - 更改条形图中最后一个元素的颜色
- terraform - Terraform 错误`属性“vpc_zone_identifier”的值不合适:元素 0:需要字符串。`
- nvme - 如何获取 NVMe 队列属性
- php - 如何将多个复选框值传递给php
- sql - 执行包含在 SQL Server 中的列中的字符串
- this - 这指的是对象
- c++ - 如何使用矢量元素将项目添加到结构中?
- sql - SQL Server 存储过程即使在刷新后也不刷新
- python - 调整 LSTM 模型