如何让 Go channel worker 有不同的结果长度?

我从gobyexample做了一些编辑:

import (

    "fmt"

    "math/rand"

    "time"

)


type DemoResult struct {

    Name string

    Rate int

}


func random(min, max int) int {

    rand.Seed(time.Now().UTC().UnixNano())

    return rand.Intn(max-min) + min

}


func worker(id int, jobs <-chan int, results chan<- DemoResult) {

    for j := range jobs {

        fmt.Println("worker", id, "started  job", j)

        time.Sleep(time.Second)

        fmt.Println("worker", id, "finished job", j)

        myrand := random(1, 4)

        if myrand == 2 {

            results <- DemoResult{Name: "succ", Rate: j}

        }

        //  else {

        //  results <- DemoResult{Name: "failed", Rate: 999}

        // }

    }

}


func main() {

    const numJobs = 5

    jobs := make(chan int, numJobs)

    results := make(chan DemoResult)

    for w := 1; w <= 3; w++ {

        go worker(w, jobs, results)

    }

    for j := 1; j <= numJobs; j++ {

        jobs <- j

    }

    close(jobs)


    for a := 1; a <= numJobs; a++ {

        out := <-results

        if out.Name == "succ" {

            fmt.Printf("%v\n", out)

        }

    }

}

我评论了以下代码,故意让它永远卡住:


        //  else {

        //  results <- DemoResult{Name: "failed", Rate: 999}

        // }

看起来我们应该使结果的长度与作业的长度相同。我想知道我们是否可以让它有不同的长度?


撒科打诨
浏览 72回答 2
2回答

牧羊人nacy

使用等待组来检测工作人员何时完成。工作人员完成后关闭结果通道。接收结果直到通道关闭。func worker(wg *sync.WaitGroup, id int,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobs <-chan int,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results chan<- DemoResult) {&nbsp; &nbsp; // Decrement wait group counter on return from&nbsp; &nbsp; // function.&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; ⋮&nbsp;}func main() {&nbsp; &nbsp; ⋮&nbsp; &nbsp; // Declare wait group and increment counter for&nbsp; &nbsp; // each worker.&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for w := 1; w <= 3; w++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go worker(&wg, w, jobs, results)&nbsp; &nbsp; }&nbsp; &nbsp; ⋮&nbsp; &nbsp; // Wait for workers to decrement wait group&nbsp; &nbsp; // counter to zero and close channel.&nbsp; &nbsp; // Execute in goroutine so we can continue on&nbsp;&nbsp; &nbsp; // to receiving values from results in main.&nbsp;&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(results)&nbsp; &nbsp; }()&nbsp; &nbsp; ⋮&nbsp; &nbsp; // Loop until results is closed.&nbsp; &nbsp; for out := range results {&nbsp; &nbsp; &nbsp; &nbsp;⋮&nbsp; &nbsp; }}https://go.dev/play/p/FOQwybMl7tM

慕虎7371278

我想知道我们是否可以让它有不同的长度?绝对可以,但是您需要某种方法来确定何时到达结果的末尾。这就是您的示例失败的原因 - 目前该函数假设会有numJobs(每个作业一个结果)结果并等待那么多。另一种方法是使用通道关闭来指示这一点,即(游乐场)package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "math/rand"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")type DemoResult struct {&nbsp; &nbsp; Name string&nbsp; &nbsp; Rate int}func random(min, max int) int {&nbsp; &nbsp; rand.Seed(time.Now().UTC().UnixNano())&nbsp; &nbsp; return rand.Intn(max-min) + min}func worker(id int, jobs <-chan int, results chan<- DemoResult) {&nbsp; &nbsp; for j := range jobs {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("worker", id, "started&nbsp; job", j)&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(time.Second)&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("worker", id, "finished job", j)&nbsp; &nbsp; &nbsp; &nbsp; myrand := random(1, 4)&nbsp; &nbsp; &nbsp; &nbsp; if myrand == 2 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results <- DemoResult{Name: "succ", Rate: j}&nbsp; &nbsp; &nbsp; &nbsp; } // else {&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; results <- DemoResult{Name: "failed", Rate: 999}&nbsp; &nbsp; &nbsp; &nbsp; //}&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; const numWorkers = 3&nbsp; &nbsp; const numJobs = 5&nbsp; &nbsp; jobs := make(chan int, numJobs)&nbsp; &nbsp; results := make(chan DemoResult)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(numWorkers)&nbsp; &nbsp; for w := 1; w <= numWorkers; w++ {&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; worker(w, jobs, results)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; }&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait() // Wait for go routines to complete then close results channel&nbsp; &nbsp; &nbsp; &nbsp; close(results)&nbsp; &nbsp; }()&nbsp; &nbsp; for j := 1; j <= numJobs; j++ {&nbsp; &nbsp; &nbsp; &nbsp; jobs <- j&nbsp; &nbsp; }&nbsp; &nbsp; close(jobs)&nbsp; &nbsp; for out := range results {&nbsp; &nbsp; &nbsp; &nbsp; if out.Name == "succ" {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("%v\n", out)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go