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.

Reply via email to