Yes, that is why the original code did not use a lock on the read but the read of the flag was wrong. The version I posted in the other thread works fine locally. time.Sleep() has problems in the playground
> On Aug 31, 2019, at 7:50 AM, T L <tapir....@gmail.com> wrote: > > > >> On Saturday, August 31, 2019 at 8:24:31 AM UTC-4, Robert Engels wrote: >> If you comment out the read method then all threads will block. That is the >> the behavior of an unbuffered channel - a writer blocks until a reader is >> ready. Which is why you always need a valid reader running. Unless the >> channel is closed and then the writer will panic. >> >> The code I provided is valid. > > In fact, if I comment out the write instead read part, the code will also > crash on all goroutines are blocked. > >> >>> On Aug 31, 2019, at 2:40 AM, T L <tapi...@gmail.com> wrote: >>> >>> >>> >>>> On Friday, August 30, 2019 at 1:40:33 PM UTC-4, Robert Engels wrote: >>>> You changed the Read() method incorrectly - it should be using the Read >>>> lock, not the Write lock. >>>> >>>> Still, as I pointed out when I posted it, Play has a problem where it >>>> aborts if all routines are sleeping (not just blocked), so you need to run >>>> it locally. >>> >>> My fault. But it doesn't matter, for the Read method is never called (I >>> commented it off). >>> It also crash locally for all goroutines are blocked. >>> >>>> -----Original Message----- >>>> From: T L >>>> Sent: Aug 30, 2019 12:05 PM >>>> To: golang-nuts >>>> Subject: Re: [go-nuts] An old problem: lack of priority select cases >>>> >>>> >>>> >>>>> On Friday, August 30, 2019 at 12:39:41 PM UTC-4, Robert Engels wrote: >>>>> >>>>> Makes no difference in the code I posted.... as long as they all use the >>>>> same MultiWriterChannel. In fact, others can be late started, as they >>>>> will fail fast if the channel is already closed. >>>> >>>> https://play.golang.org/p/pcwIu2w8ZRb >>>> >>>> All go routines are blocked in the modified version. >>>> >>>>> -----Original Message----- >>>>> From: T L >>>>> Sent: Aug 30, 2019 11:13 AM >>>>> To: golang-nuts >>>>> Subject: Re: [go-nuts] An old problem: lack of priority select cases >>>>> >>>>> >>>>> >>>>>> On Friday, August 30, 2019 at 10:35:29 AM UTC-4, Robert Engels wrote: >>>>>> I don't think so. Why do you think that is the case? The RWLock is >>>>>> "fair" in the sense that once the 'closer' attempts to get the lock, it >>>>>> is guaranteed to get it (as the code is structured) - the subsequent >>>>>> readers will queue behind the "writer = closer". >>>>> >>>>> How about unknown/random number of senders and readers? >>>>> >>>>>> >>>>>> -----Original Message----- >>>>>> From: T L >>>>>> Sent: Aug 30, 2019 8:50 AM >>>>>> To: golang-nuts >>>>>> Subject: Re: [go-nuts] An old problem: lack of priority select cases >>>>>> >>>>>> @Robert >>>>>> I think there is a difference between the code of @Leo and you. >>>>>> In you code, the Wirte/Read/Close are all possible to block for ever. >>>>>> >>>>>>> On Thursday, August 29, 2019 at 8:59:10 PM UTC-4, Robert Engels wrote: >>>>>>> >>>>>>> Oops. You are right. The original used two different methods Closed() >>>>>>> and Read() and when I refactored I forgot to add the Read lock to the >>>>>>> Read(). That's why you always have code reviews... >>>>>>> -----Original Message----- >>>>>>> From: T L >>>>>>> Sent: Aug 29, 2019 6:25 PM >>>>>>> To: golang-nuts >>>>>>> Subject: Re: [go-nuts] An old problem: lack of priority select cases >>>>>>> >>>>>>> >>>>>>> >>>>>>>> On Wednesday, August 28, 2019 at 10:05:06 PM UTC-4, robert engels >>>>>>>> wrote: >>>>>>>> Here is a version using RWLock https://play.golang.org/p/YOwuYFiqtlf >>>>>>> >>>>>>> Doesn't the Read method need to be guarded by the reader lock? >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> It won’t run correctly in the playground because it terminates when >>>>>>>> all routines are asleep - which happens during the test (not sure why >>>>>>>> it does this, as sleeping is different than a deadlock). >>>>>>>> >>>>>>>> It is probably less efficient, and less orderly than the other example >>>>>>>> using WaitGroup but you get the idea I hope. It forcibly terminates >>>>>>>> the writers before they complete by design. >>>>>>>> >>>>>>>>> On Aug 28, 2019, at 4:09 PM, Michel Levieux <m.le...@capitaldata.fr> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> One should also be careful regarding the conceptual demands he or she >>>>>>>>> is making. >>>>>>>>> Having a shared resource (that is complex enough that it cannot be >>>>>>>>> atomically accessed or modified) means essentially that "having >>>>>>>>> multiple writers being transparent to the readers", fundamentally, is >>>>>>>>> not possible. >>>>>>>>> >>>>>>>>> From the moment itself when such a resource is shared, there must be >>>>>>>>> some sort of mecanism (that one using resources atomically usable) >>>>>>>>> that ensures the integrity of it. >>>>>>>>> Maybe what you're talking about is having it transparent in terms of >>>>>>>>> code, in which case we both agree, but if you're looking for >>>>>>>>> something transparent in essence, as in performance, logical >>>>>>>>> construction and all the rest, I think there is a misunderstanding >>>>>>>>> here: even if it was added in the language, there would be many many >>>>>>>>> things going on under the hood, as it is already (and cannot really >>>>>>>>> be otherwise) for channel use alone. >>>>>>>>> >>>>>>>>> As for the priority using selects, I think it's more of something to >>>>>>>>> be dealt with on the "user-side". There are many kinds of priority in >>>>>>>>> general, and trying to implement something in the language itself >>>>>>>>> would IMO either be too specific compared to the nessecary time to do >>>>>>>>> so or it would probably have a huge overhead on the "classical' use >>>>>>>>> case of the select construct. >>>>>>>>> + the fact that it is apparently already possible using RWMutexes. >>>>>>>>> >>>>>>>>>> Le mer. 28 août 2019 à 22:37, Marcin Romaszewicz <mar...@gmail.com> >>>>>>>>>> a écrit : >>>>>>>>>> Think of a channel as existing for the lifetime of a particular data >>>>>>>>>> stream, and not have it be associated with either producer or >>>>>>>>>> consumer. Here's an example: >>>>>>>>>> >>>>>>>>>> https://play.golang.org/p/aEAXXtz2X1g >>>>>>>>>> >>>>>>>>>> The channel here is closed after all producers have exited, and all >>>>>>>>>> consumers continue to run until the channel is drained of data. >>>>>>>>>> >>>>>>>>>> The producers are managed by something somewhere in your code - and >>>>>>>>>> that is the scope at which it makes sense to create channel >>>>>>>>>> ownership. I've used a waitgroup to ensure that the channel is >>>>>>>>>> closed after all producers exit, but you can use whatever barrier >>>>>>>>>> construct you want. >>>>>>>>>> >>>>>>>>>> Even if you must have a channel per producer, you can safely close >>>>>>>>>> the producer side, without notifying the downstream about this. The >>>>>>>>>> example early in the thread uses multiple channels, with one channel >>>>>>>>>> being used to signal that the producers should exit. Channels aren't >>>>>>>>>> really the right model for this, you want a thread safe flag of some >>>>>>>>>> sort. For example: >>>>>>>>>> >>>>>>>>>> var exitFlag uint64 >>>>>>>>>> func producer(chan data int, wg *sync.WaitGroup) { >>>>>>>>>> defer wg.Done() >>>>>>>>>> for { >>>>>>>>>> shouldExit := atomic.LoadUint64(&exitFlag) >>>>>>>>>> if shouldExit == 1 { >>>>>>>>>> return >>>>>>>>>> } >>>>>>>>>> chan <- rand.Intn(100) >>>>>>>>>> } >>>>>>>>>> } >>>>>>>>>> >>>>>>>>>> Here's 10 producers and 3 consumers sharing a channel and closing it >>>>>>>>>> safely upon receiving an exit flag: >>>>>>>>>> https://play.golang.org/p/RiKi1PGVSvF >>>>>>>>>> >>>>>>>>>> -- Marcin >>>>>>>>>> >>>>>>>>>>> On Wed, Aug 28, 2019 at 11:29 AM Leo Lara <l...@leopoldolara.com> >>>>>>>>>>> wrote: >>>>>>>>>>> I do not think priority select is *necessary*, it could be a nice >>>>>>>>>>> addition if the performance does not change. >>>>>>>>>>> >>>>>>>>>>>> On Wednesday, August 28, 2019 at 8:27:36 PM UTC+2, Leo Lara wrote: >>>>>>>>>>>> Hi Robert, >>>>>>>>>>>> >>>>>>>>>>>> From the article: """To bound more the problem, in my case, you >>>>>>>>>>>> control the writers but not the readers""" >>>>>>>>>>>> >>>>>>>>>>>> So what I was trying to do was to be able to close, with mutiple >>>>>>>>>>>> writers, while being transparent for the readers. The readers only >>>>>>>>>>>> need to read as usual form the channel. >>>>>>>>>>>> >>>>>>>>>>>> For example, if you want to write a library where the user just >>>>>>>>>>>> reads from a channel, this is an approach I found where the user >>>>>>>>>>>> of the lirbary deos nto have to do anything special. Of course, >>>>>>>>>>>> there might be another solution, but if you need to modify the >>>>>>>>>>>> reader we are talking about a different problem. >>>>>>>>>>>> >>>>>>>>>>>> Cheers!! >>>>>>>>>>>> >>>>>>>>>>>>> On Wednesday, August 28, 2019 at 7:17:24 PM UTC+2, Robert Engels >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> A better solution is to wrap the writes using a RWLock, grab the >>>>>>>>>>>>> read lock for writing, and the Write lock for closing. Pretty >>>>>>>>>>>>> simple. >>>>>>>>>>>>> >>>>>>>>>>>>> Just encapsulate it all in a MultiWriterChannel struct - generics >>>>>>>>>>>>> would help here :) >>>>>>>>>>>>> >>>>>>>>>>>>> -----Original Message----- >>>>>>>>>>>>> From: Leo Lara >>>>>>>>>>>>> Sent: Aug 28, 2019 11:24 AM >>>>>>>>>>>>> To: golang-nuts >>>>>>>>>>>>> Subject: [go-nuts] Re: An old problem: lack of priority select >>>>>>>>>>>>> cases >>>>>>>>>>>>> >>>>>>>>>>>>> This is connected with my article: >>>>>>>>>>>>> https://dev.to/leolara/closing-a-go-channel-written-by-several-goroutines-52j2 >>>>>>>>>>>>> >>>>>>>>>>>>> I think there I show it is possible to workaround that limitation >>>>>>>>>>>>> using standard Go tools. Of course, the code would be simple with >>>>>>>>>>>>> priority select, but also perhaps select would become less >>>>>>>>>>>>> efficient. >>>>>>>>>>>>> >>>>>>>>>>>>>> On Wednesday, August 28, 2019 at 6:06:33 PM UTC+2, T L wrote: >>>>>>>>>>>>>> The old thread: >>>>>>>>>>>>>> https://groups.google.com/forum/#!topic/golang-nuts/ZrVIhHCrR9o >>>>>>>>>>>>>> >>>>>>>>>>>>>> Go channels are flexible, but in practice, I often encountered >>>>>>>>>>>>>> some situations in which channel are hard to use. >>>>>>>>>>>>>> Given an example: >>>>>>>>>>>>>> >>>>>>>>>>>>>> import "math/rand" >>>>>>>>>>>>>> >>>>>>>>>>>>>> type Producer struct { >>>>>>>>>>>>>> data chan int >>>>>>>>>>>>>> closed chan struct{} >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> func NewProducer() *Producer { >>>>>>>>>>>>>> p := &Producer { >>>>>>>>>>>>>> data: make(chan int), >>>>>>>>>>>>>> closed: make(chan struct{}), >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> go p.run() >>>>>>>>>>>>>> >>>>>>>>>>>>>> return p >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> func (p *Produce) Stream() chan int { >>>>>>>>>>>>>> return p.data >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> func (p *Producer) run() { >>>>>>>>>>>>>> for { >>>>>>>>>>>>>> // If non-blocking cases are selected by their >>>>>>>>>>>>>> appearance order, >>>>>>>>>>>>>> // then the following slect block is a perfect use. >>>>>>>>>>>>>> select { >>>>>>>>>>>>>> case(0) <-p.closed: return >>>>>>>>>>>>>> case p.data <- rand.Int(): >>>>>>>>>>>>>> } >>>>>>>>>>>>>> } >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> func (p *Produce) Clsoe() { >>>>>>>>>>>>>> close(p.closed) >>>>>>>>>>>>>> close(p.data) >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> func main() { >>>>>>>>>>>>>> p := NewProducer() >>>>>>>>>>>>>> for n := p.Stream() { >>>>>>>>>>>>>> // use n ... >>>>>>>>>>>>>> } >>>>>>>>>>>>>> } >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> If the first case in the select block in the above example has a >>>>>>>>>>>>>> higher priority than the second one, >>>>>>>>>>>>>> then coding will be much happier for the use cases like the >>>>>>>>>>>>>> above one. >>>>>>>>>>>>>> >>>>>>>>>>>>>> In short, the above use case requires: >>>>>>>>>>>>>> * for receivers, data streaming end is notified by the close of >>>>>>>>>>>>>> a channel. >>>>>>>>>>>>>> * for senders, data will never be sent to closed channel. >>>>>>>>>>>>>> >>>>>>>>>>>>>> But, as Go 1 doesn't support priority select cases, it is much >>>>>>>>>>>>>> tedious to implement the code >>>>>>>>>>>>>> satisfying the above listed requirements. The final >>>>>>>>>>>>>> implementation is often very ugly and inefficient. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Does anyone else also experience the pain? >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> 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. >>>>>>>>>>>>> To view this discussion on the web visit >>>>>>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/b284f880-034a-4721-8686-ef48d3e2c14c%40googlegroups.com. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> 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. >>>>>>>>>>> To view this discussion on the web visit >>>>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/aeb38a0a-8268-42d7-a8eb-ce5ef01c5380%40googlegroups.com. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> 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. >>>>>>>>>> To view this discussion on the web visit >>>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/CA%2Bv29LvcUhUvrZb_8AKYWj0A%2Bqd5LKBPmbz-RVBb%3DJn_gNZE6w%40mail.gmail.com. >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> 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. >>>>>>>>> To view this discussion on the web visit >>>>>>>>> https://groups.google.com/d/msgid/golang-nuts/CANgi337s1Low95QvqJUAOTsqcVji7uMQ_jr%3DFftpt2uMz5_XSQ%40mail.gmail.com. >>>>>>>> >>>>>>> >>>>>>> -- >>>>>>> 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. >>>>>>> To view this discussion on the web visit >>>>>>> https://groups.google.com/d/msgid/golang-nuts/a5cff3f8-cc1c-4719-9f2f-7b9c31086f6a%40googlegroups.com. >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> 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. >>>>>> To view this discussion on the web visit >>>>>> https://groups.google.com/d/msgid/golang-nuts/4bf95bb2-33ed-46ed-9436-48df1072914f%40googlegroups.com. >>>>>> >>>>>> >>>>>> >>>>> >>>>> -- >>>>> 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. >>>>> To view this discussion on the web visit >>>>> https://groups.google.com/d/msgid/golang-nuts/d155dcf6-7c01-4f7e-b408-eef9903cd837%40googlegroups.com. >>>>> >>>>> >>>>> >>>> >>>> -- >>>> 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. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/golang-nuts/74653e49-f374-4ac8-998e-fd874cdf6bd4%40googlegroups.com. >>>> >>>> >>>> >>> >>> -- >>> 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. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/3d75a129-efee-402f-aafa-9fe76af4e789%40googlegroups.com. > > -- > 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/dfdf8905-f740-434c-a293-d801de4f71dc%40googlegroups.com. -- 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/04EF5C06-955B-45F1-9246-5B7329401035%40ix.netcom.com.