猿问

如何编写更好的双通道选择

在下面的代码中有两个包含工作的通道 A 和 B,在实际代码中它们是不同的结构,工作人员需要在退出之前排空两个通道。工作人员需要来自两个渠道的信息。这两个 select 语句可以工作,但非常笨拙。如果我添加default:以使它们非阻塞,则代码无法排出通道。有没有更好的方式来编写选择?


现在,如果通道 A 没有工作,则通道 B 也不会得到服务。另一个需要解决的问题,但不是我主要关心的问题。


用于测试以下代码的游乐场:


package main


import (

    "fmt"

    "time"

)


const (

    fillCount  = 10 // number of elements in each input channel

    numWorkers = 3  // number of consumers.

)


func Wait() {

    time.Sleep(2000 * time.Millisecond)

}


func fillChannel(work chan string, name string) {

    for i := 0; i < fillCount; i++ {

        work <- fmt.Sprintf("%s%d", name, i)

    }

    close(work) // we're finished

}


func doWork(id int, ch1 chan string, ch2 chan string, done chan bool) {

    fmt.Println("Running worker", id)

    defer fmt.Println("Ending worker", id)


    for ch1Open, ch2Open := true, true; ch1Open && ch2Open; {

        cnt1 := len(ch1)

        cnt2 := len(ch2)


        if ch1Open {

            select {

            case str, more := <-ch1:

                if more {

                    fmt.Printf("%d: ch1(%d) %s\n", id, cnt1, str)

                } else {

                    fmt.Printf("%d: ch1 closed\n", id)

                    ch1Open = false

                }

            }

        }


        if ch2Open {

            select {

            case str, more := <-ch2:

                if more {

                    fmt.Printf("%d: ch2(%d) %s\n", id, cnt2, str)

                } else {

                    fmt.Printf("%d: ch2 closed\n", id)

                    ch2Open = false

                }

            }

        }

    }

    done <- true

}


func main() {


    a := make(chan string, 2) // a small channel

    b := make(chan string, 5) // a bigger channel


    // generate work

    go fillChannel(a, "A")

    go fillChannel(b, "B")


    // launch the consumers

    done := make(chan bool)


    for i := 0; i < numWorkers; i++ {

        go doWork(i, a, b, done)

    }


    // wait for the goroutines to finish.

    for i := 0; i < numWorkers; i++ {

        <-done

    }


catspeake
浏览 169回答 1
1回答
随时随地看视频慕课网APP

相关分类

Go
我要回答