切片范围超出范围

时间:2020-06-14 06:14:30

标签: go concurrency goroutine

以下代码引发slice bounds out of range错误。

func main()  {
    file, err := os.Open("mails.mbox")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    m := mbox.NewReader(file) // bufio.NewScanner(file)

    for {
        data, err := m.NextMessage() // .Scan()
        if err == io.EOF {
            break
        } else if err != nil {
            log.Fatalf("Unexpected error after NextMessage(): %v", err)
        }
        go saveMessage(data)
    }

    // By now we should not have any messages inside.
    if _, err := m.NextMessage(); err != io.EOF {
        log.Fatalf("We still have data: %v", err)
    }
}

func saveMessage(data io.Reader) {
    msg, err := mail.ReadMessage(data)
    if err != nil {
        return
    }
    // insert msg into database
}

我想同时处理saveMessage函数。

一次

100或基于可用内存。

1 个答案:

答案 0 :(得分:1)

从NextMessage返回的mbox阅读器和消息阅读器对于并发访问并不安全。由于mbox实现中存在数据争夺,该程序感到恐慌。

通过在启动goroutine之前先对消息数据进行分析来解决:

for {
    data, err := m.NextMessage() // .Scan()
    if err == io.EOF {
        break
    } else if err != nil {
        log.Fatalf("Unexpected error after NextMessage(): %v", err)
    }
    msg, err := mail.ReadMessage(data)
    if err != nil {
       log.Fatal(err)
    }
    go saveMessage(msg)
}

...

func saveMessage(msg *mail.Message) {
    // insert msg into database
}