fredag 30. april 2021 kl. 02:45:02 UTC+2 skrev Ian Lance Taylor:

> On Thu, Apr 29, 2021 at 12:05 PM Øyvind Teig <oyvin...@teigfam.net> 
> wrote: 
> > 
> > The example here is a server with N clients where it is essential that 
> none of clients will starve and none jam the server. I have needed to do 
> this coding several times. Go has random select which in theory may mean 
> starving and jamming. I worked with safety critical fire detection, and it 
> was necessary to ensure this. Or at least we didn't dare to take the 
> chance. We could not just add another machine. 
> > 
> > To use select when that's fair enough (pun 1) - "fair enough" (pun 2). 
> But If I want to be certain of no starving or jamming I need to code the 
> fairness algorithm. I can then promise a client that may have been ready 
> but wasn't served to come in before I take the previous clients that were 
> allowed. This is at best very difficult if all we have is select. Having 
> pri select as the starting point is, in this case, easier. 
>
> When there are multiple ready results, the select statement in Go is 
> guaranteed to use a uniform pseudo-random selection 
> (https://golang.org/ref/spec#Select_statements). The fact that cases 
> are selected using a uniform distribution ensures that executing a 
> select statement in a loop can't lead to starving (I'm not sure what 
> jamming is). 
>
> As several people have said, it's meaningless to say "I want to ensure 
> that if both case A and case B are available then the select statement 
> will choose case A." It's meaningless because it relies on a notion 
> of simultaneity that literally doesn't exist. 


I have a stomach feeling that I agree with you. I will still argue against. 
I just wish someone could pinpoint where these standpoints clash, or don't. 

If there is no notion of simultaneity why all the effort to describe the 
random distribution? 

The select is first set up, at which time the code decides on which one to 
take if more than one guard is ready. If the clients were only sending, 
then nowhere in the system is this noted on "the other" side of the channel 
(in the server) before it enters the select. The channel would have noted 
the first contender, yes, but the servre have yet no idea. If none is 
ready, then the server was first on all the ends, and when a sender arrives 
it will match the guard set in the server and tear down the select. In due 
time the server is scheduled with that one event.

This is how I have seen it in several systems. I wonder what might be so 
different with go.
 

> There will always be a 
> period of time after the select statement chooses B, but before it 
> actually executes the case, that case A may become ready. That will 
> be true for any possible implementation of select, because select is 
> not an atomic operation. 
>
> Therefore, this code using a hypothetical priority case 
>
> select { 
> case pri <-c1: 
> case <-c2: 
> } 
>
> can always be rewritten as 
>
> select { 
> case <-c1: 
> default: 
> select { 
> case <-c1: 
> case <-c2: 
> } 
> } 
>
> The rewritten select is exactly equivalent to the first. The only way 
> that they could not be equivalent would be if select were atomic. 
>

Ok, so this is a pattern that Go people would use if they needed to do pri 
select. Then, why go to the lengths of the other code shown above? Is it 
because I have kind of "pressed" you to come up with code and then of 
course, one thing may be solved several ways? 

Will your Go code examples stand the test of formal verification? Of 
course, when it's not formally verified you probaby could not answer such a 
question. But the stomach feeling?

Another angle: Go does not have the expression before the select that 
evaluates to true or false. Nothing like

select { 
case (do_this) => val1 <-c1: 
case val2  <-c2: 
} 

Instead, the chan is set to nil to exclude it from the set. What might 
happen if we had a set of 100 clients and they were switched on and off 
internally in the server (that's their purpose) - when will the uniform 
distribution be reset? What's the life span of the distribution? With a 
psudorandom sequence any one value is only visited once on a round. We 
still want this to be fair. Could those having been served be served again 
(before the others) after a reset of the distribution, and this introduce a 
notion of unfairness?

 (I gues that jamming is that only one client alone gets to the server, 
whereas starving is that a client never gets to the server).

Øyvind
 

>
> Ian 
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ec5e5c0f-c5bf-4efb-b1c4-dc056720ba5cn%40googlegroups.com.

Reply via email to