--
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/6992b605-ff10-4659-8016-dd96066d4588%40googlegroups.com.
You need to code it knowing that either can occur in any order.
On Sep 8, 2019, at 10:14 AM, changkun <euryu...@gmail.com> wrote:
Hi, golang nuts,Let's think about this snippet: https://play.golang.org/p/3cNGho3gWTGIn the code snippet, a ticker is activating and another that that is closing, it seems that they can happen concurrently and resultin two different outcomes: either ticker case being executed first or the other way around.It is because of the pseudo-randomization of the select statement.Intuitively, the close statement should happens-before select statement that starts choosing which caseshould be executing, and select a closed channel with the highest priority to prevent another receive case being executed once more.My questions are:Does the Go team or anybody else think of this memory order before? What was the decision that didn't make it?If not, is it worth to be defined within the language? There are no language changes and only affects the runtime implementation.--
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.
The provided code snipped on my machine can result in different outputs, which basically shows that it could occur in any order.
The randomization mechanism in select statement made the verification hard. Logically, my argument is rigorous
--
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/d1c412e6-c775-49a6-8d1d-c417497dc9be%40googlegroups.com.
Intuitively, the close statement should happens-before select statement that starts choosing which caseshould be executing, and select a closed channel with the highest priority to prevent another receive case being executed once more.
My questions are:Does the Go team or anybody else think of this memory order before? What was the decision that didn't make it?If not, is it worth to be defined within the language? There are no language changes and only affects the runtime implementation.
--
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/6992b605-ff10-4659-8016-dd96066d4588%40googlegroups.com.
First: The close *does* happen-before the case clause of the select for the closed channel, as per the memory model.
Second: If you actually establish an ordering "close happens-before the select statement, which happens-before the ticker firing", you should actually get the result you want, in that only the close-case is deterministically chosen, AIUI. So we are only talking about the case you tried to enforce, where you *don't* have that ordering - that is, where the close happens concurrently with the ticker firing and both happen concurrently to the select starting to execute.
// goroutine1
closedCh := make(chan struct{})
// do some preparation
...
for {
select {
case <- ticker.C:
// it is possible that this case can still being executed
// one more time if closedCh arrives.
// heartbeat detection, data processing..
...
case <- closedCh
return
}
// goroutine2
close(closedCh)
// "global" data
closedCh := make(chan struct{})
closed := uint32(0)
// goroutine1
// do some preparation
...
for {
select {
case <- ticker.C:
// now it is ok
if atomic.LoadUint32(&closed) == 1 {
return
}
// heartbeat detection, data processing..
...
case <- closedCh
return
}
// goroutine2
if !atomic.CompareAndSwapUint32(&closed, 0, 1) {
return ErrClosed
}
close(closedCh)
Now, ISTM that the simplest intuitive interpretation of what "event A and B happen concurrently" (defined abstractly as "are not ordered in the happens-before partial order) is that the order that A and B happen in real time in is unclear and could happen either way olin practice. And under that intuitive understanding, I don't know how you conclude that the select should prioritize either or not execute the ticker case at all. After all - you can never know whether the ticker *has actually fired* at the concrete real point in time the select executed.
Note, by the way, that the fact that you observe either result doesn't actually say anything about the pseudo-randomness or lack thereof of the select statement: You can't, from the output of the program, distinguish between "both cases where ready to proceed and select flipped a coin coming up close" from "only close was ready to proceed, because select executed in between the closing/firing" (and the same for the timer firing). The pseudo-randomness of select is irrelevant for your case, it's the fact that these events are concurrent, both as specified and IMO as intuitively obvious.
Here comes with more interesting points. My "intuitive" comes from this scenario:I have an unbuffered channel "closedCh" that indicates if a network connection is closed, a timer handles for heartbeat detection and polls some data, if a connection is closed, then returns an error.At some point, I close the "closedCh" for the termination of previous for-select loop.I initially thought that the heartbeat detection case will not be executed andclosedCh will safely return and terminates the loop.However, there are some "false negative" results returned by the loop,because select still can select the heartbeat case if the heartbeat and closedCh arrive concurrently.
--
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/7736fea9-b4c0-4b1b-8b0e-9bc3b0e3bd7b%40googlegroups.com.