package doublecheck
import (
"sync"
)
type Once struct {
m sync.Mutex
done uint32
}
func (o *Once) Do(f func()) {
if o.done == 1 {
return
}
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
o.done = 1
f()
}
}
Question
Hello,
Hi,
Thanks for your reply.
The second bug is a known issue, so let’s ignore that. In that case, I think function f still can only be executed once.
But why does the load and store of o.done need to be done using atomic operations? I suppose there’s mutex assuring the happens-before.
--
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/CABx2%3DD8hZAt0DRyrTEnunU2%3D6_y2hheDB48RZft7BAS4a7fEcg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
It seems clear to me that C ("can run but has not implemented the singleton pattern, function f may run multi times") is not the correct answer, because I'm pretty sure that f cannot run more than once.However, it's still not a correct Once implementation, because as has already been pointed out, the Do method can return before the function has completed.The reason why f cannot run more than once is that if you don't have the initial non-atomic test of o.done, then the function cannot run more than once, and the extra condition only reduces the number of times that f can be called.The implementation would be incorrect even if the `o.done = 1` assignment was moved before the call to f, because there's no happens-before relationship between the `o.done == 1` check and either of the statements within the mutex. This means that it's possible for the `o.done == 1` check to report true but for the caller to see memory that indicates that f hasn't been called.If you run this code with the race detector enabled, it will report an error. That should be good enough reason not to use code like this.Here's a complete example: https://play.golang.org/p/vWVXzRBPMNeThe question is: according to the Go memory model, what's the set of possible things that that program can print?I think it could print "unexpected value 0" but not "unexpected value 2".
On Wed, 8 May 2019 at 05:49, Kurtis Rader <kra...@skepticism.us> wrote:
--On Tue, May 7, 2019 at 9:42 PM White Pure <wu.pu...@gmail.com> wrote:--Hi,
Thanks for your reply.
The second bug is a known issue, so let’s ignore that. In that case, I think function f still can only be executed once.
But why does the load and store of o.done need to be done using atomic operations? I suppose there’s mutex assuring the happens-before.You seem to be using two different email accounts to comment on this thread. That is confusing, at best, and sock puppeting, at worst. Don't do that.Also, your text in the message I am replying to is in a very light grey color. Which makes it hard to read on a white background. Please don't use styled text that modifies the colors on a general purpose mailing list. Not everyone is using color preferences compatible with your preferences.Kurtis RaderCaretaker of the exceptional canines Junior and Hank
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 golan...@googlegroups.com.