>source

다른 고 루틴이 파일 읽기를 완료 할 때까지 기다리지 않고 파일에서 데이터를 읽고 즉시 청크 읽기를 보내려고합니다. 두 가지 기능이 있습니다

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 플래그로 프로그램을 실행하면 데이터 경합이 있고 두 개의 고 루틴이 동시에 채널에 쓰고 읽습니다. 솔직히 말해서 그것이 채널을 사용하는 일반적인 방법이라고 생각했지만 이제는 더 많은 문제가 발생한다는 것을 알았습니다. 누군가이 문제를 해결하도록 도와 주시겠습니까?

  • 답변 # 1

    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 [sic]에서 읽는 동안 ReadFile에서 덮어 씁니다. 이것이 경주 감지기를 트리거해서는 안되지만 확실히 버그입니다. 각 Read 호출에 대해 새 슬라이스를 만듭니다.

     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)
    
    

관련 자료

  • 이전 java - 여러 줄 목록을 세로로 포맷하는 방법
  • 다음 r - ggplot의 미적 특성을 높이는 방법은 무엇입니까?