Неверный вывод из буферизованного диапазона канала в подпрограмме GO - PullRequest
0 голосов
/ 13 декабря 2018

Почему подпрограмма 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 строк выходных данных в качестве примера того, что я имею в виду для "неработающий"output ":

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 голосов
/ 13 декабря 2018

Из документов buffer.Scanner:

Базовый массив может указывать на данные, которые будут перезаписаны при последующем вызове Scan

У вас есть гонка данных вокруг использования срезов, которые вы передаете по каналу.Вам необходимо скопировать данные, которые вы отправляете.В этом примере это проще всего сделать, используя string вместо []byte и вызвав scanner.Text

...