阅读,从执行程序的通道没有阻塞

0

的问题

我有两个go程序:主 worker 和一个 helper 它的旋转关闭一些帮助。 helper 可能会遇到错误,所以我使用一个信道的通信错误的 helper 来的 worker.

func helper(c chan <- error) (){
    //do some work
    c <- err // send errors/nil on c
}

这里是怎么 helper() 被称为:

func worker() error {
    //do some work
    c := make(chan error, 1)
    go helper(c)
    err := <- c
    return err
}

问题:

  • 是的声明 err := <- c 阻挡 worker? 我不这么认为,由于道缓冲。

  • 如果这是阻挡,如何使它无阻塞? 我的要求是要有 worker 和它的呼叫者继续与其余的工作,而没有 等待 对于该价值出现在的通道。

谢谢。

channel go goroutine
2021-11-24 01:59:57
3

最好的答案

2

你可以很容易地验证

func helper(c chan<- error) {
    time.Sleep(5 * time.Second)
    c <- errors.New("") // send errors/nil on c
}

func worker() error {
    fmt.Println("do one")

    c := make(chan error, 1)
    go helper(c)

    err := <-c
    fmt.Println("do two")

    return err
}

func main() {
    worker()
}

问:该声明的错误:=<-c阻止工人? 我不这么认为,由于道缓冲。

A: err := <- c 将块工作人员。

问:如果它是阻挡,如何使它无阻塞? 我的要求是要有工作和它的呼叫者继续与其余的工作,而不必等待该价值出现在的通道。

一: 如果你不想阻挡的,只是删除 err := <-c. 如果你需要err结束时,只需移动 err := <-c 到底。

你可以不读通道没有阻挡,如果你通过无阻,可以可以没有更多的exec这样的代码,除非你的代码是一个循环。

Loop:
    for {
        select {
        case <-c:
            break Loop
        default:
            //default will go through without blocking
        }
        // do something
    }

和你有没有看到 errgroup 或waitgroup?

它利用原子,取消上下文并不同步。一旦实现这一点。

https://github.com/golang/sync/blob/master/errgroup/errgroup.go

https://github.com/golang/go/blob/master/src/sync/waitgroup.go

或者你可以使用它,去你func然后等待错你想要的任何地方。

2021-12-01 21:31:34
1

在你的代码,其余的工作是独立于是否帮助遇到了一个错误。 你可以简单地接收从通道之后的其余部分的工作完成。

func worker() error {
    //do some work
    c := make(chan error, 1)
    go helper(c)
    //do rest of the work
    return <-c
}
2021-11-24 02:54:28

好了,不会的工人()被阻止,直到一个值出现在 c?
Someone

此外,我刚刚编辑 worker(). 它返回的错误/nil到它的呼叫者。 因此,将这种操作可以阻止吗?
Someone

是的那个特定的操作框直到帮助发送一个 errornil 该频道。 但是,工作人员被阻止后,才完成其所有工作。
Chandra Sekar

但是这块叫的 worker. 是否有办法使它无阻塞?
Someone

如果工作人员,因此它的呼叫者,并没有等待帮助完成的,它可以如何返回的错误帮手?
Chandra Sekar
0

我觉得你需要这个代码..

运行这个代码

package main

import (
    "log"
    "sync"
)

func helper(c chan<- error) {

    for {
        var err error = nil
        // do job

        if err != nil {
            c <- err // send errors/nil on c
            break
        }
    }

}

func worker(c chan error) error {
    log.Println("first log")

    go func() {
        helper(c)
    }()

    count := 1
    Loop:
        for {
            select {
            case err := <- c :
                return err
            default:
                log.Println(count, " log")
                count++
                isFinished := false
                // do your job
                if isFinished {
                    break Loop // remove this when you test

                }
            }
        }
    return nil
}

func main() {
    wg := sync.WaitGroup{}
    wg.Add(1)
    go func() {
        c := make(chan error, 1)
        worker(c)
        wg.Done()
    }()
    wg.Wait()
}
2021-11-24 02:35:53

你能解释一下,通过的方式编辑,以此回答,为什么这会有帮助吗? 我不知道,如果,将是有用的,如果不是问题的作者,未来的读者。
halfer

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................