缓冲golang通道丢失数据

缓冲golang通道丢失数据,go,blocking,channel,Go,Blocking,Channel,我试图使用goroutine解析一个巨大的Wiktional转储,但遇到了一个奇怪的错误,goroutine读取的通道每次阻塞时似乎都会丢失和损坏数据 func main() { inFile, err := os.Open(*srcFile) if err != nil { log.LogErrorf("Error opening dump: %v", err) return } defer inFile.Close()

我试图使用goroutine解析一个巨大的Wiktional转储,但遇到了一个奇怪的错误,goroutine读取的通道每次阻塞时似乎都会丢失和损坏数据

func main() {
    inFile, err := os.Open(*srcFile)
    if err != nil {
        log.LogErrorf("Error opening dump: %v", err)
        return
    }
    defer inFile.Close()

    var wg sync.WaitGroup
    input := make(chan []byte, 51)


    go func() {
        wg.Add(1)
        for line := range input {
            log.Printf("Bytes: %s", line)
            // process the line
        }
        wg.Done()
    }()

    scanner := bufio.NewScanner(inFile)
    count := 0
    for scanner.Scan() {
        count++
        log.Printf("Scanned: %d", count)
        if err := scanner.Err(); err != nil {
            log.LogErrorf("Error scanning: %v", err)
        }
        newestBytes := scanner.Bytes()
        log.Printf("Bytes: %s", newestBytes)
        input <- newestBytes
    }
    close(input)
    wg.Wait()
}
func main(){
infle,err:=os.Open(*srcFile)
如果错误!=零{
LogErrorf(“打开转储时出错:%v”,err)
返回
}
延迟填充。关闭()
var wg sync.WaitGroup
输入:=make(chan[]字节,51)
go func(){
工作组.添加(1)
对于行:=范围输入{
log.Printf(“字节:%s”,第行)
//处理生产线
}
wg.Done()
}()
扫描仪:=bufio.NewScanner(内嵌)
计数:=0
对于scanner.Scan(){
计数++
log.Printf(“扫描:%d”,计数)
如果错误:=scanner.err();错误!=nil{
LogErrorf(“错误扫描:%v”,错误)
}
newestBytes:=scanner.Bytes()
log.Printf(“字节数:%s”,最新字节数)
输入该函数可能返回扫描仪内部使用的相同切片

Bytes返回由扫描调用生成的最新令牌。基础数组可能指向将被后续扫描调用覆盖的数据。它不进行分配

根据文档,后续调用
Scanner.Scan
,可能会覆盖此切片。因为您的代码无法确保在下次调用
Scanner.Scan
(事实上,您的代码生成行并异步使用它们)后不使用此切片,它可能在您试图使用它的位置包含垃圾

显式复制切片,以确保后续调用
Scanner.Scan
不会覆盖数据

input <- append(nil, newestBytes...)

input我无法编译您的示例。您在哪里声明
fanIn
?请注意,以后调用
scanner.Scan()
可能会覆盖scanner.Bytes()返回的切片
根据文档。您从不复制该片段的内容,并且显然假定该内容没有被覆盖,这是错误的。哦,对不起,应该输入fanIn。此外,您还需要用您自己的字符串或其他东西替换srcFile标志,可能还有其他一些东西。我编辑了代码以突出显示频道,所以它可能不可编译。@fuzzxl-hmm这可以解释它跳过行。但我仍然不确定它为什么会损坏数据。实际上,不,这是有意义的。如果scanner.Bytes()切片指向基础数组上的不同位置,并且数组被更改,那么这些切片确实可能指向无意义的块。
Bytes:       <namespace key="828" case="case-sensitive">Module</namespace>
2014/08/03 17:40:52 Bytes:       <namespace key="829" case="case-sensitive">Module talk</namespace>
2014/08/03 17:40:52 Bytes:     </namespaces>
2014/08/03 17:40:52 Bytes:   </siteinfo>
2014/08/03 17:40:52 Bytes:   <page>
2014/08/03 17:40:52 Bytes:     <title>Wiktionary:Welcome, newcomers</title>
2014/08/03 17:40:52 Scanned: 52
2014/08/03 17:40:52 Scanned: 53
2014/08/03 17:40:52 Scanned: 54
2014/08/03 17:40:52 Scanned: 55
2014/08/03 17:40:52 Scanned: 56
2014/08/03 17:40:52 Scanned: 57
2014/08/03 17:40:52 Scanned: 58
2014/08/03 17:40:52 Scanned: 59
2014/08/03 17:40:52 Scanned: 60
2014/08/03 17:40:52 Scanned: 61
2014/08/03 17:40:52 Scanned: 62
2014/08/03 17:40:52 Scanned: 63
2014/08/03 17:40:52 Scanned: 64
2014/08/03 17:40:52 Scanned: 65
2014/08/03 17:40:52 Scanned: 66
2014/08/03 17:40:52 Scanned: 67
2014/08/03 17:40:52 Scanned: 68
2014/08/03 17:40:52 Scanned: 69
2014/08/03 17:40:52 Scanned: 70
2014/08/03 17:40:52 Scanned: 71
2014/08/03 17:40:52 Scanned: 72
2014/08/03 17:40:52 Scanned: 73
2014/08/03 17:40:52 Scanned: 74
2014/08/03 17:40:52 Scanned: 75
2014/08/03 17:40:52 Scanned: 76
2014/08/03 17:40:52 Scanned: 77
2014/08/03 17:40:52 Scanned: 78
2014/08/03 17:40:52 Scanned: 79
2014/08/03 17:40:52 Scanned: 80
2014/08/03 17:40:52 Scanned: 81
2014/08/03 17:40:52 Scanned: 82
2014/08/03 17:40:52 Scanned: 83
2014/08/03 17:40:52 Scanned: 84
2014/08/03 17:40:52 Scanned: 85
2014/08/03 17:40:52 Scanned: 86
2014/08/03 17:40:52 Scanned: 87
2014/08/03 17:40:52 Scanned: 88
2014/08/03 17:40:52 Scanned: 89
2014/08/03 17:40:52 Scanned: 90
2014/08/03 17:40:52 Scanned: 91
2014/08/03 17:40:52 Scanned: 92
2014/08/03 17:40:52 Scanned: 93
2014/08/03 17:40:52 Scanned: 94
2014/08/03 17:40:52 Scanned: 95
2014/08/03 17:40:52 Scanned: 96
2014/08/03 17:40:52 Scanned: 97
2014/08/03 17:40:52 Scanned: 98
2014/08/03 17:40:52 Scanned: 99
2014/08/03 17:40:52 Scanned: 100
2014/08/03 17:40:52 Scanned: 101
2014/08/03 17:40:52 Scanned: 102
2014/08/03 17:40:52 Bytes: nd other refer
2014/08/03 17:40:52 Bytes: nce and instru
2014/08/03 17:40:52 Bytes: tional materials. It stipulates that any copy of the material,
2014/08/03 17:40:52 Bytes: even if modifi
2014/08/03 17:40:52 Bytes: d, carry the same licen
2014/08/03 17:40:52 Bytes: e. Those copies may be sold but, if
2014/08/03 17:40:52 Bytes: produced in quantity, have to be made available i
2014/08/03 17:40:52 Bytes:  a format which fac
2014/08/03 17:40:52 Bytes: litates further editing. 
func (s *Scanner) Bytes() []byte
input <- append(nil, newestBytes...)