Thanks Robert, Daves article is mind opening. I created 4 variants of my program to compare the effects and to give others the chance to study it:
1. https://play.golang.org/p/WE_CbRlfTFf 2. https://play.golang.org/p/FnuzyEVHS-I 3. https://play.golang.org/p/S9ssTxlZK6X 4. https://play.golang.org/p/XHLGfjYUP17 For the moment I will go for the second variant with buffered and disabled channels. Thanks to all! Am Di., 18. Dez. 2018 um 21:03 Uhr schrieb robert engels < reng...@ix.netcom.com>: > This may be a helpful read: > > https://dave.cheney.net/2013/04/30/curious-channels > > On Dec 18, 2018, at 2:02 PM, robert engels <reng...@ix.netcom.com> wrote: > > To clarify the semantics aspects: > > If A cannot proceed until B performs it’s work, because there is a > dependency, then using a unbuffered channel simplifies a lot - you will > always be at most “one event ahead” without any extra synchronization (wait > groups, etc.) > > On Dec 18, 2018, at 2:01 PM, robert engels <reng...@ix.netcom.com> wrote: > > Whether to use buffered or unbuffered comes down to two things: > > 1) the semantics of the communication. because using unbuffered channels > simplifies a lot - knowing the send will not complete until the read > completes - it provides a synchronization mechanism between events/messages > and routines. > > 2) performance… imagine the following pseudo code: > > routine A sends messages to routine B > routine B's processing of messages is variable - sometimes very fast, > sometimes very slow… > --- for example, let B be a logger, that every once in a while needs > to write to disk (the much slower operation) > > so if A is a low latency event processor - getting stuck trying to send to > B would not be ideal - but since this only happens ‘rarely’ by using a > buffered channel (with the size = number of events expected in a B “slow” > time), you avoid “blocking” A > > for example, A is sending financial orders to an exchange - you would not > want to every slow A down just because the logger was slow > > For the performance aspect, you are essentially increasing the > parallelism, since any “block/wait” degrades this > > Hope that helps. > > > > On Dec 18, 2018, at 1:49 PM, Chris Burkert <burkert.ch...@gmail.com> > wrote: > > Robert, > it seems to me that you have a clear understanding about unbuffered vs. > buffered channels. I feel unbuffered channels are safer to use especially > in an acyclic directed graph of flowing values. Buffered channels seem to > reduce blocking but I feel they come with the cost of such side effects > like my initial problem of forgotten results in their channels. I would > love to hear/read/see more on the unbuffered vs. buffered tradeoff to get > rid of this gut feeling I am currently based on :-). Any good article you > can point me to? > Thanks > > Robert Engels <reng...@ix.netcom.com> schrieb am Di. 18. Dez. 2018 um > 17:03: > >> That code is incorrect as well when using buffered channels. >> >> On Dec 18, 2018, at 10:00 AM, Skip Tavakkolian < >> skip.tavakkol...@gmail.com> wrote: >> >> why not just drop the select? i think the following is guaranteed >> because putting things on rc has to succeed before putting true into dc: >> >> package main >> >> import ( >> "fmt" >> ) >> >> func do(i int, rc chan<- int, dc chan<- bool) { >> rc <- i >> dc <- true >> } >> >> func main() { >> worker := 10 >> rc := make(chan int, worker) >> done := 0 >> dc := make(chan bool, worker) >> for i := 0; i < worker; i++ { >> go do(i, rc, dc) >> } >> for done < worker { >> r := <-rc >> fmt.Println(r) >> <-dc >> done++ >> } >> } >> >> >> On Tue, Dec 18, 2018 at 5:35 AM Chris Burkert <burkert.ch...@gmail.com> >> wrote: >> >>> Dear all, >>> >>> I have a couple of goroutines sending multiple results over a channel - >>> a simple fan-in. They signal the completion on a done channel. Main selects >>> on the results and done channel in parallel. As the select is random main >>> sometimes misses to select the last result. What would be the idiomatic way >>> to prevent this and completely drain the result channel? >>> >>> Here is a minmal example which sometimes prints one 0 but should always >>> print two of them: >>> >>> package main >>> >>> import ( >>> "fmt" >>> ) >>> >>> func do(rc chan<- int, dc chan<- bool) { >>> rc <- 0 >>> dc <- true >>> } >>> >>> func main() { >>> worker := 2 >>> rc := make(chan int, worker) >>> done := 0 >>> dc := make(chan bool, worker) >>> for i := 0; i < worker; i++ { >>> go do(rc, dc) >>> } >>> for done < worker { >>> select { >>> case <-dc: >>> done++ >>> case r := <-rc: >>> fmt.Println(r) >>> } >>> } >>> } >>> >>> many thanks >>> Chris >>> >>> -- >>> 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. >>> >> >> -- >> 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. >> >> > > > -- 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.