最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

concurrency - or-done-channel pattern in Go - why no return inside inner select and what happens if both done and producer chann

programmeradmin0浏览0评论

Reading Concurrency in Go.

Trying to understand the or-done-channel pattern.

Having trouble wrapping my head around the execution flow.

I have mentioned number against the line where my doubt is from.

  1. Why no return statement in inner <-done like we have in outer select? Because of no return statement, the next iteration will run and what if in that iteration we have both <- done and <-c available. We know select-case will choose any of the case arbitrarily if multiple cases are available. Does this mean there is a possibility that <-c will run even if <-done was available?

  2. Since select-case arbitrarily chooses a case when multiple case are available, is it correct to assume that the <- done will be chosen eventually but it is not necessary that it is chosen immediately as soon as it is closed. Of Course, this doubt is when both case i.e. <-done and <-c were available.

  3. There is a possibility that <- v is not written onto valStream when done is closed and it is lost forever, correct?

orDone := func(done, c <-chan interface{}) <-chan interface{} {
    valStream := make(chan interface{})
    go func() {
        defer close(valStream)
        for {
            select {                   //2
            case <-done:
                return
            case v, ok := <-c:
                if ok == false {
                    return
                }
                select {
                case valStream <- v:   //3
                case <-done:           //1
                }
            }
        }
    }()
    return valStream
}

Basically, either correct me if I'm wrong or confirm that my understanding of the execution is correct. There indeed are "loopholes" with the code and that is just channel behaviour here.

Similar Question here

Reading Concurrency in Go.

Trying to understand the or-done-channel pattern.

Having trouble wrapping my head around the execution flow.

I have mentioned number against the line where my doubt is from.

  1. Why no return statement in inner <-done like we have in outer select? Because of no return statement, the next iteration will run and what if in that iteration we have both <- done and <-c available. We know select-case will choose any of the case arbitrarily if multiple cases are available. Does this mean there is a possibility that <-c will run even if <-done was available?

  2. Since select-case arbitrarily chooses a case when multiple case are available, is it correct to assume that the <- done will be chosen eventually but it is not necessary that it is chosen immediately as soon as it is closed. Of Course, this doubt is when both case i.e. <-done and <-c were available.

  3. There is a possibility that <- v is not written onto valStream when done is closed and it is lost forever, correct?

orDone := func(done, c <-chan interface{}) <-chan interface{} {
    valStream := make(chan interface{})
    go func() {
        defer close(valStream)
        for {
            select {                   //2
            case <-done:
                return
            case v, ok := <-c:
                if ok == false {
                    return
                }
                select {
                case valStream <- v:   //3
                case <-done:           //1
                }
            }
        }
    }()
    return valStream
}

Basically, either correct me if I'm wrong or confirm that my understanding of the execution is correct. There indeed are "loopholes" with the code and that is just channel behaviour here.

Similar Question here

Share Improve this question edited Feb 6 at 16:39 Burak Serdar 51.5k4 gold badges48 silver badges69 bronze badges asked Feb 6 at 16:03 user10089194user10089194 3692 gold badges5 silver badges16 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1
  1. Inner select <-done case should also have a return. This code is relying on the outer select to capture <-done, which may not happen immediately
  2. If <-done is available it will be chosen eventually. It is likely that it will be chosen quickly, but you are correct. There is no guarantee that even if the inner select chooses <-done, the outer will chose it as well in its next iteration.
  3. If <-done is available, then yes, there is a possibility that v will be read but won't be written

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论