Pergunta

  var x int
  done := false
  go func() { x = f(...); done = true }
  while done == false { }

This is a Go code piece. My fiend told me this is UB code. Why?

Foi útil?

Solução

As explained in "Why does this program terminate on my system but not on playground?"

The Go Memory Model does not guarantee that the value written to x in the goroutine will ever be observed by the main program.
A similarly erroneous program is given as an example in the section on go routine destruction.
The Go Memory Model also specifically calls out busy waiting without synchronization as an incorrect idiom in this section.

(in your case, there is no guarantee that the value written to done in the goroutine will ever be observed by the main program)

Here, You need to do some kind of synchronization in the goroutine in order to guarantee that done=true happens before one of the iterations of the for loop in main.

The "while" (non-existent in Go) should be replaced by, for instance, a channel you block on (waiting for a communication)

for {
    <-c // 2
}

Based on a channel (c := make(chan bool)) created in main, and closed (close(c)) in the goroutine.


The sync package provides other means to wait for a gorountine to end before exiting main.

See for instance Golang Example Wait until all the background goroutine finish:

var w sync.WaitGroup
w.Add(1)
go func() {
    // do something
    w.Done()
}
w.Wait()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top