New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ref/mem: misleading sentence in sync.Once example #27808
Comments
The channel is not necessary to the example: the goroutines are scheduled eventually, they're just not guaranteed to schedule before the program exits (if it does exit).
The “first call” in the context of that sentence is the first call that “happens” in the happens-before relationship. There is not well-defined “first call” to You're right that the sentence “The first call to The important sentence in that section is:
|
As noted above: there is no “first call […] to begin executing the The important behavior of |
A clearer fix might be to change the sentence:
to
|
That's a good point. I'm pondering this, because I think there's a mild ambiguity there, but on reflection, I think it's just the general ambiguity that nothing promises that code ever executes at all. For instance, so far as I can tell, if a hostile implementor looked at the sample code, and decided that they could prove that two things would eventually reach the once.Do(), they would be allowed to implement it so that the first goroutine to reach that point necessarily blocks, and the second is allowed to run the provided function. But I guess that doesn't actually matter at all, as long as they don't block indefinitely for no particular reason. Hmm. Come to think of it:
Shouldn't that be "for a particular
|
On reading docs and trying it: It clearly should, given that the docs for |
Change https://golang.org/cl/155637 mentions this issue: |
What version of Go are you using (
go version
)?1.11/playground
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?linux/amd64, playground
What did you do?
https://play.golang.org/p/w-CNHDQAGW-
What did you expect to see?
according to ref/mem as written, "1\n1 hello, 1\n2\n 2 hello 1\n"
What did you see instead?
the other way around
Observation: There's two things here that I think are potentially misleading, although both are sort of trivial. The first is that, according to the "goroutine destruction" section, there's no guarantee that anything gets printed, because nothing is waiting on these, and indeed, without the extra channel operations, nothing happens.
The second is the distinction between "the first call to doprint()", "the first call to doprint() which actually starts execution", and "the first call to doprint() which actually begins the once.Do() call". While in the trivial example, probably the first call to start executing will win that, it's not generally a given that two goroutines acting in parallel will always complete in the same order they start, even running identical code. But in particular, it's definitely not guaranteed that the "first call" will start executing first.
I'm fine with handwaving the synchronization thing, but I think the wording on "the first call" might benefit from cleaning up. Proposed wording:
The first call to
doprint()
to begin executing theonce.Do()
callssetup()
, any calls that reach that point later do not, regardless of the order in which the goroutines are invoked or begin executing.The text was updated successfully, but these errors were encountered: