On Friday, May 11, 2018 at 11:54:16 AM UTC-4, Jake Montgomery wrote: > > As others on this thread have pointed out, this use case does not actually > require select where the cases are checked in order. > > However, for completeness, if you need to check two channels, and they > must be checked in order, then use two select statements with defaults: > for { > select { > case wi := <-work_ch: > self.do_the_work(wi) > default: > } > select { > case <-self.idle_request: > self.idle_response <- true > default: > } > } > > Again, this should rarely be necessary, or even useful. But there it is. >
Good point, but it is too cpu consuming. I think the following one is better. for { select { case <-self.idle_request: self.idle_response <- true default: } select { case wi := <-work_ch: self.do_the_work(wi) case <-self.idle_request: self.idle_response <- true } } But I think if it would be even better if Go support non-random select blocks. > > > On Friday, May 4, 2018 at 10:24:56 AM UTC-4, Andriy Pylypenko wrote: >> >> Hi, >> >> I have a scenario which I haven't found a way to implement with the Go >> channels and select statement while it's no problem to do it with the >> select()/poll() functions. The scenario is as follows. >> >> Let me use a Go-like pseudo-code to demonstrate the idea. There is a >> source of a work items which are processed by several goroutines. Here is >> the source procedure: >> >> work_ch := make(chan *WorkItem) >> >> for { >> work_ch <- NewWorkItem() >> } >> >> And here is the worker thread: >> >> for { >> wi := <-work_ch >> self.do_the_work(wi) >> } >> >> Now I need to suspend the work. I stop supplying the work items and want >> to make sure the worker goroutines are done with the work. The source >> procedure becomes something like this: >> >> for { >> if suspend_requested { >> for _, worker := range workers { >> worker.idle_request <- true >> } >> for _, worker := range workers { >> <-worker.idle_response >> } >> report_suspend_is_success() >> wait_until_unsuspended() >> } >> work_ch <- NewWorkItem() >> } >> >> And I want to modify the worker thread like this: >> >> for { >> select { >> case wi := <- work_ch: >> self.do_the_work(wi) >> case <-self.idle_request: >> self.idle_response <- true >> } >> } >> >> However this last snippet of code does not work because the cases within >> the select statement are randomly chosen when both channels are ready so I >> have no guarantee that the first case is executed first. >> >> Talking about the select() or poll() functions from the C library which >> evidently were an inspiration for the Go select statement, there is no >> problem with the described approach. It's because the select() function >> returns a complete information about the state of all the monitored >> descriptors and allows the programmer to decide what he wants to read or >> write and in which order, based on readiness of every descriptor. >> >> I think it would be a great idea to have some function similar to >> select()/poll() but working with the Go channels. >> > -- 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. For more options, visit https://groups.google.com/d/optout.