Para el siguiente código:

Lector.go

func (r *Reader) ReadData(objCh chan *data.InputEntry, stopCh chan struct{}) {

    var object data.InputEntry

    go func() {
        for {
            ....
            jsonErr := json.Unmarshal(byteBuffer[:n], &object) // Line 55
             ...    
            objCh <- &object
        }

    }()
}

Escritor.go

func (w *Processor) ProcessData(objectCh chan *data.InputEntry, stopCh chan struct{}) {

    go func() {
        for {
            object, wd := <-objectCh
            ...    
            w.Log.Printf("Received object: %v\n", object) // Line 83


        }
    }()
}

A continuación se muestra el error:

WARNING: DATA RACE
Write at 0x00c000138000 by goroutine 7:
  reflect.Value.SetString()
      /usr/local/go/src/reflect/value.go:1712 +0xb3
  encoding/json.(*decodeState).literalStore()
      /usr/local/go/src/encoding/json/decode.go:972 +0x3179
  encoding/json.(*decodeState).value()
      /usr/local/go/src/encoding/json/decode.go:401 +0x2dc
  encoding/json.(*decodeState).object()
      /usr/local/go/src/encoding/json/decode.go:782 +0x225e
  encoding/json.(*decodeState).value()
      /usr/local/go/src/encoding/json/decode.go:387 +0xaf
  encoding/json.(*decodeState).unmarshal()
      /usr/local/go/src/encoding/json/decode.go:180 +0x27a
  encoding/json.Unmarshal()
      /usr/local/go/src/encoding/json/decode.go:107 +0x1de
  github.com/myhub/code/reader.(*Reader).ReadData.func1()
      /home/../code/src/github.com/myhub/code/reader/reader.go:55 +0x385

Previous read at 0x00c000138000 by goroutine 8:
  reflect.typedmemmove()
      /usr/local/go/src/runtime/mbarrier.go:177 +0x0
  reflect.packEface()
      /usr/local/go/src/reflect/value.go:119 +0x126
  reflect.valueInterface()
      /usr/local/go/src/reflect/value.go:1023 +0x1b9
  reflect.Value.Interface()
      /usr/local/go/src/reflect/value.go:993 +0x3c27
  fmt.(*pp).printValue()
      /usr/local/go/src/fmt/print.go:726 +0x3c28
  fmt.(*pp).printValue()
      /usr/local/go/src/fmt/print.go:880 +0x2709
  fmt.(*pp).printArg()
      /usr/local/go/src/fmt/print.go:716 +0x25a
  fmt.(*pp).doPrintf()
      /usr/local/go/src/fmt/print.go:1030 +0x311
  fmt.Sprintf()
      /usr/local/go/src/fmt/print.go:219 +0x73
  log.(*Logger).Printf()
      /usr/local/go/src/log/log.go:188 +0x64
  github.com/myhub/code/writer.(*Processor).ProcessData.func1()
      /home/../code/src/github.com/myhub/code/writer/writer.go:83 +0xa5

Goroutine 7 (running) created at:
    github.com/myhub/code/reader.(*Reader).ReadData()
      /home/../code/src/github.com/myhub/code/reader/reader.go:41 +0xb5
  main.main()
      /home/../code/src/github.com/myhub/code/main.go:42 +0x10c

Goroutine 8 (running) created at:
  github.com/myhub/code/writer.(*Processor).ProcessData()
      /home/../code/src/github.com/myhub/code/writer/writer.go:75 +0x60
  main.main()
      /home/../code/src/github.com/myhub/code/main.go:44 +0x12e
==================

La carrera de datos está entre la línea 55 (reader.go) y la línea 83 (writer.go)

¿Cómo resolver este error?

go
-3
overexchange 1 sep. 2020 a las 04:59

1 respuesta

La mejor respuesta

Está enviando la dirección de una variable de una goroutine a la otra, y luego lee / escribe en esa variable desde ambas goroutines, es decir, object.

La solución es pasar object como valor o redefinir el objeto para cada iteración en el lector. En la implementación actual del lector, object se define en la función que inicia la goroutine. No parece haber ninguna razón para ello. Simplemente declare object en el bucle for en la goroutine.

go func() {
    for {
         ....
         var object data.InputData
         jsonErr := json.Unmarshal(byteBuffer[:n], &object)
             ...    
         objCh <- &object
    }
}()

O:

go func() {
    for {
         ....
         jsonErr := json.Unmarshal(byteBuffer[:n], &object)
             ...    
         objCh <- object
    }
}()
1
Burak Serdar 1 sep. 2020 a las 02:29