从文件中读取数据并同时发送数据时出现数据竞争问题

Data race issues while reading data from file and sending it simultaneously

我正在尝试从文件中读取数据并立即将读取的数据块发送给它,而无需等待其他 goroutine 完成文件读取。我有两个功能

func ReadFile(stream chan []byte, stop chan bool) {
    file.Lock()
    defer file.Unlock()
    dir, _ := os.Getwd()
    file, _ := os.Open(dir + "/someFile.json")
    chunk := make([]byte, 512*4)
    for {
        bytesRead, err := file.Read(chunk)
        if err == io.EOF {
            break
        }
        if err != nil {
            panic(err)
            break
        }
        stream <- chunk[:bytesRead]
    }

    stop <- true
}

第一个负责读取文件并将数据块发送到从另一个函数接收的“流”通道

func SteamFile() {
    stream := make(chan []byte)
    stop := make(chan bool)

    go ReadFile(stream, stop)

L:
    for {
        select {
        case data := <-stream:
            //want to send data chunk by socket here
            fmt.Println(data)
        case <-stop:
            break L
        }
    }
}

第二个函数创建 2 个通道,将它们发送到第一个函数并开始收听通道。 问题是有时 data := <-stream 会丢失。例如,我没有收到文件的第一部分,但收到了所有其他部分。当我 运行 带有 -race 标志的程序时,它告诉我们存在数据竞争,并且两个 goroutine 同时写入和读取通道。说实话,我认为这是使用频道的正常方式,但现在我发现它带来了更多问题。 有人可以帮我解决这个问题吗?

When I run the program with -race flag it tells that there is a data race and two goroutines write to and read from the channel simultaneously. To tell the truth I thought that's the normal way do use channels.

是的,您几乎肯定误解了竞争检测器的输出。

您在 ReadFile 中共享切片(因此它是底层数组),因此在 SteamFile [原文如此] 中读取数据时,数据在 ReadFile 中被覆盖。虽然这不应该触发竞争检测器,但这绝对是一个错误。为每个读取调用创建一个新切片:

  func ReadFile(stream chan []byte, stop chan bool) {
      file.Lock()
      defer file.Unlock()
      dir, _ := os.Getwd()
      file, _ := os.Open(dir + "/someFile.json")
-     chunk := make([]byte, 512*4)
      for {
+         chunk := make([]byte, 512*4)
          bytesRead, err := file.Read(chunk)