golang在goroutine里的错误怎么传递?

首先goroutine真的很爽。。。 场景是这样的,就是要把goroutine里的错误消息传递出来,简单的代码示例:

    func work(some string, ch chan string){
        // do something
        err:=dosomething()
        for{
            select{
            case <-ch:
                // do something
                err:=doOthersome()
            }
        }
    }

    func main(){
        go work(some, ch)
        //  在这里如何得到work函数里的err
    }

我现在用的是在main函数里定义一个chan error,传递给work,然后在work里有err的时候,给这个chan error发消息,在main函数里接收,但这样如果没有err,会导致main函数阻塞。

    func work(some string, ch chan string, chanErr chan error){
        // do something
        err:=dosomething()
        if err!=nil{
            chanErr<-err
            return
        }
        for{
            select{
            case <-ch:
                // do something
                err:=doOthersome()
                if err!=nil{
                    chanErr<-err
                    return
                }
            }
        }
    }

    func main(){
    chanErr:=make(chan error)
        go work(some, ch, chanErr)
        //  在这里接收work函数里的err, 没有任何错误的话会阻塞
        err:=<-chanErr
    }

来请教大家,有没有更好的方法?不让main函数阻塞

已邀请:

tonyluj - Go

赞同来自: sheepbao SoloMagic

可以参考 https://godoc.org/golang.org/x/sync/errgroup

var g errgroup.Group
var urls = []string{
    "http://www.golang.org/",
    "http://www.google.com/",
    "http://www.somestupidname.com/",
}
for _, url := range urls {
    // Launch a goroutine to fetch the URL.
    url := url // https://golang.org/doc/faq#closures_and_goroutines
    g.Go(func() error {
        // Fetch the URL.
        resp, err := http.Get(url)
        if err == nil {
            resp.Body.Close()
        }
        return err
    })
}
// Wait for all HTTP fetches to complete.
if err := g.Wait(); err == nil {
    fmt.Println("Successfully fetched all URLs.")
}

themoonstone - 90后IT男

赞同来自: sheepbao

你这里用的是select、可以无论有没有产生err都给它传值:我贴代码你看一下、测试没问题

package main

import (
    "errors"
    "fmt"
    "math/rand"
    "time"
)

var timeout chan bool

func worker(ch chan int, ch_err chan error) {
    for {
        select {
        case data := <-ch:
            if data%2 != 0 {
                ch_err <- errors.New("ji shu")
                return
            } else {
                ch_err <- nil
            }
        case <-timeout:
            return
        default:
            ch_err <- nil
        }
    }
}

func main() {
    cherr := make(chan error)
    ch := make(chan int)
    data := rand.Int()
    timeout = make(chan bool)

    go worker(ch, cherr)
    go func() {
        ch <- data
        time.Sleep(time.Second)
        timeout <- true
    }()
    fmt.Println(<-cherr)
}

要回复问题请先登录注册