torsdag 6. mai 2021 kl. 22:08:31 UTC+2 skrev Peter Wilson: > Back in the days of transputers and occam, there was a desire to be able > to manage all interesting events in a system in a within-language (language > being occam) manner. > Interrupts were a problem, because you can't describe interrupts as > implemented by microprocessors (steal the PC and jump somewhere, saving > minimal state) in a language which doesn't discuss stealing the PC nor what > minimal state might be. > > So there were two scenarios handled. > > In one scenario, you created a high-priority process (occam had > priorities) and had it wait on a hardware channel. If a signal arrived from > hardware which would normally interrupt (in a classic microprocessor), it > delivered a message to the hardware channel, and the waiting process work > up pre-empting the execution of any currently-executing lower-priority > process. This is a close approximation to the behaviour of classic device > interrupts with the limitation of a single level of interrupt priority, the > latter being imposed by the implementation of the transputers, not the > language. This works fine if the high priority process is completely > 'individualistic', and doesn't need to tell other processes anything > (because then you fall direct into the second scenario, albeit in another > process). > > In the other scenario, you had what we might look upon as sorta an object > which got asked to do different sorts of things. All the requests arrived > by messages on separate (unbuffered at the time) channels. The PRI ALT > simply said that for one reason or another, if requests arrived on several > channels while the process was busy doing other stuff, then it must choose > to service the highest priority channel. It was still up to the software > designer to be sure that the time the process was busy was not so long that > the priority was useless. > > So to model classic prioritised interrupts, you would consider than > handling an interrupt - classically, someone mashes the Big Red Button on a > software controlled black box implemented by a number of communicating > processes, requiring it to stop as close to Right Now as possible - as a > message to a high-priority process, which would perform any immediate, > time-critical operation (turning off the electricity to the black box?) and > then send a message to a lower priority process in charge of the general > state of the black box to tidy up internal state. Then you really want > there to be a PRI ALT, because the black box isn't running any more and > handling useless messages from prior 'clients' is just silly - you want the > 'big red button mashed' message to be taken in preference to anything else. > > And the dual notions of process priority and select priority work together > well to make it clear what the designer's intents were. Such transparency > is valuable. > > It can be argued that go isn't and wasn't ever intended to deal with such > scenarios, and so the provision of priorities in goroutines and selects is > not an interesting capability. >
Thanks for the summary! I do recognise the scenarios. But from an acadamic point of view I think Go is indeed interesting simply because <a href="https://golang.org/doc/faq#csp">Why build concurrency on the ideas of CSP?</a>. It's interesting to see xC/xCORE in view of your discussion. It's designed by some of the same people with many of the problems you describe in mind. Øyvind > On Thursday, May 6, 2021 at 2:41:11 PM UTC-5 ren...@ix.netcom.com wrote: > >> But that is not really true because there are no constraints on if the >> source channels are buffered - if they are then my code operates similarly. >> >> Even if using unbuffered channels there is buffering being done at a >> lower level (hardware buffers, network stack buffers, etc) - so not >> “unblocking a sender” is a dubious endeavor. >> >> On May 6, 2021, at 1:30 PM, 'Axel Wagner' via golang-nuts < >> golan...@googlegroups.com> wrote: >> >> >> >> On Thu, May 6, 2021 at 8:22 PM Robert Engels <ren...@ix.netcom.com> >> wrote: >> >>> “If lo” means that if the lo channel was read. >>> >> >> Exactly. To fulfill the requirements and answering the question, it must >> not be read. >> >> This code will prevent a lo from being processed if a hi is available at >>> the happens before moment of a value being ready. >>> >> >> What the receiver does with the value is immaterial. Point is, that the >> receiver has already read the value, thus the communication has happened, >> thus the sender was unblocked. The question is about a select that wouldn't >> do that. >> >> >>> Btw using indents rather than brackets in the above - maybe that is >>> causing the confusion. >>> >> >> I'm not confused. Your code is simply not answering the question posed. >> Which is about a select which always lets the high priority communication >> happen, if it is ready before the low priority communication - and >> consequently *doesn't* let the low priority communication happen. >> >> >>> >>> >>> >>> On May 6, 2021, at 12:37 PM, 'Axel Wagner' via golang-nuts < >>> golan...@googlegroups.com> wrote: >>> >>> >>> No, it is not. Your "if lo" branch implies that the communication >>> happened - e.g. the sender was already unblocked. A `select` would not >>> unblock the other side unless that's the actual branch taken. >>> >>> On Thu, May 6, 2021 at 7:32 PM Robert Engels <ren...@ix.netcom.com> >>> wrote: >>> >>>> I already showed you - just change it to >>>> >>>> Select hi >>>> Default: >>>> Select hi,lo >>>> If lo: >>>> Select hi >>>> Default : >>>> Pass >>>> >>>> And enqueue the lo if a hi and lo are read. >>>> >>>> That is all that is needed. >>>> >>>> >>>> >>>> On May 6, 2021, at 10:28 AM, 'Axel Wagner' via golang-nuts < >>>> golan...@googlegroups.com> wrote: >>>> >>>> >>>> >>>> >>>> On Thu, May 6, 2021 at 4:43 PM roger peppe <rogp...@gmail.com> wrote: >>>> >>>>> >>>>> On Thu, 6 May 2021 at 14:41, 'Axel Wagner' via golang-nuts < >>>>> golan...@googlegroups.com> wrote: >>>>> >>>>>> PS: And I'm not saying there is no argument. Maybe "select is not >>>>>> atomic" is such an argument. But if there is an argument and/or if this >>>>>> is >>>>>> that argument, I don't fully understand it myself. >>>>>> >>>>> >>>>> One reason is that the semantics can conflict. Consider this code, for >>>>> example (assuming a hypothetical "pri select" statement that chooses the >>>>> first ready arm of the select) - the priorities conflict. I suspect Occam >>>>> doesn't encounter that issue because it only allows (or at least, it did >>>>> back when I used Occam) select on input, not output. I believe that >>>>> restriction was due to the difficulty of implementing bidirectional >>>>> select >>>>> between actual distributed hardware processors, but I'm sure Øyvind knows >>>>> better. >>>>> >>>>> func main() { >>>>> c1, c2, c3 := make(chan int), make(chan int), make(chan int) >>>>> >>>>> go func() { >>>>> pri select { >>>>> case c1 <- 1: >>>>> case v := <-c2: >>>>> c3 <- v >>>>> } >>>>> }() >>>>> go func() { >>>>> pri select { >>>>> case c2 <- 2: >>>>> case v := <-c1: >>>>> c3 <- v >>>>> } >>>>> }() >>>>> fmt.Println(<-c3) >>>>> } >>>>> >>>> >>>> Interesting case. I would argue, though, that there is no >>>> happens-before edge here to order the cases and I was only considering >>>> providing a guarantee if there is one. >>>> >>>> >>>>> That said, I suspect that the semantics could be ironed out, and the >>>>> real reason for Go's lack is that it's not actually that useful; that it >>>>> would be one more feature; and that in practice a random choice makes >>>>> sense >>>>> almost all the time. >>>>> >>>> >>>> As I said, this would certainly satisfy me as an answer :) >>>> >>>> >>>>> >>>>> >>>>> On Thu, May 6, 2021 at 3:40 PM Axel Wagner <axel.wa...@googlemail.com> >>>>>> wrote: >>>>>> >>>>>>> FWIW after all this discussion I *am* curious about a more detailed >>>>>>> argument for why we can't have a priority select that guarantees that >>>>>>> *if* the high-priority case becomes ready before the low-priority >>>>>>> one (in the sense of "there exists a happens-before edge according to >>>>>>> the >>>>>>> memory model"), the high-priority will always be chosen. >>>>>>> >>>>>>> That is, in the example I posted above >>>>>>> <https://play.golang.org/p/UUA7nRFdyJE>, we *do* know that `hi` >>>>>>> becoming readable happens-before `lo` becoming readable, so a true >>>>>>> prioritized select would always choose `hi` and never return. The >>>>>>> construct >>>>>>> we presented *does* return. >>>>>>> >>>>>>> Now, I do 100% agree that it's not possible to have a select that >>>>>>> guarantees that `hi` will be read if both *become readable >>>>>>> concurrently*. But I don't see a *fundamental* issue with having a >>>>>>> select that always chooses `hi` if `*hi` becoming readable >>>>>>> happens-before `lo` becoming readable*. >>>>>>> >>>>>>> And to be clear, I also kinda like that we don't have that - I think >>>>>>> the value provided by the pseudo-random choice in preventing starvation >>>>>>> is >>>>>>> worth not having an "ideal" priority select construct in the language. >>>>>>> But >>>>>>> I couldn't really make a good case why we *can't* have it. >>>>>>> >>>>>> -- >>>>>> 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/CAEkBMfEJNtu1i1RyZxW5FNYkD0TB73nq0WyVCCW_E9_JOAVJmw%40mail.gmail.com >>>>>> >>>>>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEJNtu1i1RyZxW5FNYkD0TB73nq0WyVCCW_E9_JOAVJmw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>>>> . >>>>>> >>>>> -- >>>> 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/CAEkBMfHEEDdL8adBDFoqwVHswK3kr_KawePGi%3DNtbaBVTP5KWw%40mail.gmail.com >>>> >>>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHEEDdL8adBDFoqwVHswK3kr_KawePGi%3DNtbaBVTP5KWw%40mail.gmail.com?utm_medium=email&utm_source=footer> >>>> . >>>> >>>> -- >>> 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/CAEkBMfHv2cKR1OLS97YN7JYKZXHu_s0a-6c0-2tW%3DS0gUU8jUA%40mail.gmail.com >>> >>> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHv2cKR1OLS97YN7JYKZXHu_s0a-6c0-2tW%3DS0gUU8jUA%40mail.gmail.com?utm_medium=email&utm_source=footer> >>> . >>> >>> -- >> 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/CAEkBMfHQq2p60OenLMYUFz%3DK9HigpbAqj7m%3D%2BRp7BnCX%2Bp1QLA%40mail.gmail.com >> >> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHQq2p60OenLMYUFz%3DK9HigpbAqj7m%3D%2BRp7BnCX%2Bp1QLA%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> >> -- 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/2b095664-fac8-4e1e-b8dc-2d85b2d2530bn%40googlegroups.com.