A problem about Happens Before

81 views
Skip to first unread message

sanye

unread,
Feb 23, 2021, 2:51:28 AM2/23/21
to golang-nuts
Hello Gophers,a question bothers me while reading the doc: The Go Memory
Model

package main

var a string

func f() {
print(a)
}

func hello() {
a = "hello, world\n"
go f()
}

func main() {
hello()
}

This code snippet is OK

But if I exchange the 2 lines in function hello, DATA RACE happens, why?

Axel Wagner

unread,
Feb 23, 2021, 3:05:40 AM2/23/21
to sanye, golang-nuts
Because you have a concurrent read/write to a.
Specifically, the Memory model says that "the go statement that starts a new goroutine happens before the goroutine's execution begins". This means the first code is fine - the write happens before the go statement, which happens before execution of f begins, which happens before the `print(a)`. So the write happens before the read and everything is fine.
If you switch the two lines, the go statement still happens before execution of f begins and thus before `print(a)`. But now, it *also* happens before the write ("Within a single goroutine, reads and writes must behave as if they executed in the order specified by the program"). So the read and the write are concurrent - the go statement happens before both, but they are not ordered between them.

FTR, this should also be fairly obvious without looking at the specifics of the memory model. If you do
go f()
a = "hello world"
You start a new goroutine reading `a`, so it should be clear, that when the assignment happens, there is a separate goroutine running that might read from it at the same time.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/5b622597-6c1c-e32c-7c18-a8dab525e322%40gmail.com.

sanye

unread,
Feb 23, 2021, 3:28:27 AM2/23/21
to Axel Wagner, golang-nuts


On 2/23/21 4:04 PM, Axel Wagner wrote:
> Because you have a concurrent read/write to a.
> Specifically, the Memory model says that "the go statement that starts a
> new goroutine happens before the goroutine's execution begins"
> <https://golang.org/ref/mem#tmp_5>. This means the first code is fine -
> the write happens before the go statement, which happens before
> execution of f begins, which happens before the `print(a)`. So the write
> happens before the read and everything is fine.
> If you switch the two lines, the go statement still happens before
> execution of f begins and thus before `print(a)`. But now, it *also*
> happens before the write


("Within a single goroutine, reads and writes
> must behave as if they executed in the order specified by the program").

Thanks, dude. My main confusion is why the first code does not have DATA
RACE problem, I think I understand this sentence now.
> <mailto:golang-nuts%2Bunsu...@googlegroups.com>.
> <https://groups.google.com/d/msgid/golang-nuts/5b622597-6c1c-e32c-7c18-a8dab525e322%40gmail.com>.
>
Reply all
Reply to author
Forward
0 new messages