FAQ
Hi all,

Incase it helps, go version = go1.2.1 darwin/amd64

I have encountered an issue in unbuffered chans not synchronising even
though the chans have not been declared with any capacity. For some weird
reason, the receiving channels ends up reading duplicate values from the
channels.

Some work is being sent to be processed by a number of functions in a
pipeline that is determined at runtime. So each worker func has an input
and output chan similar to the pipelines description
here: http://blog.golang.org/pipelines

So it starts with the declaration

out := make(chan work)

go func() {

        for _, record := range ac.rc.RL {

                out <- work{ac.rc.Headers, &record}

        }

        close(out)

}()

then for each func create to process data in the pipeline
var nxt <-chan work = out
for _, w := range ac.rw {
  nxt = w.Work(nxt)
}


Each Work func declares a chan, reads from the input chan it receives in a
separate go routine and returns "out"
out := make(chan work)
go func() {
  for j := range in {
  // does something and sends result to out
  out <- result
  }
  close(out)
}()
return out


The problem is that multiple values are sent before the Work function reads
one and when that happens, it reads the same duplicate value. I'm guessing
I am doing something wrong and probably missing something obvious. When I
put a delay as tiny as 1ms (obviously not good practise), all is well.


Thanks in advance if anything is spotted that I've missed

--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Andrew Bursavich at Nov 13, 2014 at 3:34 am
    In the first snippet posted, the struct you're sending contains a pointer
    to a record value that is being reused. After you send it down the channel,
    the value that it points to is being mutated by the next iteration of the
    loop. Then there's a race when the value is read.

    http://play.golang.org/p/k4TOvHjwDP

    Cheers,
    Andy

    --
    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 [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Andrew Bursavich at Nov 13, 2014 at 3:36 am
    In the first snippet posted, the struct you're sending contains a pointer
    to a record value that is being reused. After you send it down the channel,
    the value that it points to is being mutated by the next iteration of the
    loop. Then there's a race when the value is read.

    http://play.golang.org/p/k4TOvHjwDP

    Cheers,
    Andy

    --
    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 [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Benn at Nov 13, 2014 at 7:22 pm
    Thanks Andy for that explanation. That was spot on, solved the issue and
    helped me understand what was going on.

    Thanks,

    Ben
    On Thursday, 13 November 2014 03:36:24 UTC, Andrew Bursavich wrote:

    In the first snippet posted, the struct you're sending contains a pointer
    to a record value that is being reused. After you send it down the channel,
    the value that it points to is being mutated by the next iteration of the
    loop. Then there's a race when the value is read.

    http://play.golang.org/p/k4TOvHjwDP

    Cheers,
    Andy
    --
    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 [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Andrew Bursavich at Nov 13, 2014 at 9:09 pm
    No problem. I guess it's worth mentioning that the solution I hinted at
    involves an additional allocation for every iteration. It would be more
    efficient to use a pointer to the original value in the slice's backing
    array. Of course, all synchronization concerns still apply if those values
    will be mutated. Additionally, as long as there's a single pointer hanging
    around then the entire array cannot be garbage collected.

    http://play.golang.org/p/RLnOAtRxDf

    Cheers,
    Andy

    --
    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 [email protected].
    For more options, visit https://groups.google.com/d/optout.
  • Benn at Nov 14, 2014 at 2:56 am
    Thanks.

    So considering your example, if this took place in a method called from
    main and there was second another goroutine reading the channel "ch" in
    your example.

    Will I be correct in saying "foo" will be garbage collected once the second
    goroutine has read/processed & has no reference to the last value in "foo"
    and not when this method goes out of scope?

    Additionally, when iterating the range of a channel and mutating the value
    that is pointed to, what are the other concerns (aside from deadlocking)?

    If there's a pipleline of functions, with each function iterating the range
    of a channel, I understand that if the intended behaviour is to possibly
    mutate the value pointed to, the next function in the pipleline should then
    see this change.

    --
    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 [email protected].
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 13, '14 at 3:04a
activeNov 14, '14 at 2:56a
posts6
users3
websitegolang.org

People

Translate

site design / logo © 2023 Grokbase