返回顶部
首页 > 资讯 > 精选 >如何在错误时停止从通道读取?
  • 331
分享到

如何在错误时停止从通道读取?

overflow 2024-02-09 14:02:46 331人浏览 泡泡鱼
摘要

PHP小编子墨为您介绍如何在错误时停止从通道读取。在进行通道读取操作时,有时会遇到错误情况,比如通道已关闭或者读取超时。为了保证程序的稳定性和可靠性,我们需要在这些错误发生时及时停止读

PHP小编子墨为您介绍如何在错误时停止从通道读取。在进行通道读取操作时,有时会遇到错误情况,比如通道已关闭或者读取超时。为了保证程序的稳定性和可靠性,我们需要在这些错误发生时及时停止读取操作。可以通过设置错误处理程序或使用异常处理机制来实现,在捕获到错误后,立即终止读取操作,并进行相应的错误处理。这样可以有效避免程序因错误而导致的异常情况,提高代码的健壮性和可维护性。

问题内容

一旦遇到错误,我想停止从通道读取。我认为我需要使用 errroup.WithContext() 但我无法完全理解如何集成它。

这是输出:

Thread 2: STARTED
Thread 1: STARTED
Thread 0: STARTED
Thread 2: GoT=0
Thread 1: GOT=1
Thread 0: GOT=2
Thread 0: FaiLED
Thread 1: GOT=3
Thread 2: GOT=4
Thread 2: GOT=5
Thread 1: GOT=6
Thread 1: GOT=7
Thread 2: GOT=8
panic: Thread 0: FAILED
package main

import (
    "fmt"
    "time"

    "golang.org/x/sync/errgroup"
)

func main() {
    const threads = 3

    ch := make(chan int, threads)

    eg := errgroup.Group{}

    for i := 0; i < threads; i++ {
        i := i
        eg.Go(func() error {
            fmt.Printf("Thread %d: STARTED\n", i)
            for n := range ch {
                fmt.Printf("Thread %d: GOT=%d\n", i, n)
                time.Sleep(time.Duration(1) * time.Second)
                // Simulate failed thread
                if n == 2 {
                    fmt.Printf("Thread %d: FAILED\n", i)
                    return fmt.Errorf("Thread %d: FAILED", i)
                }
            }
            return nil
        })
    }

    for i := 0; i < 9; i++ {
        ch <- i
    }

    close(ch)

    if err := eg.Wait(); err != nil {
        panic(err)
    }
}

...................................................... ......................................

解决方法

errroup.WithContext() 可能是最好的方法(正如你所猜测的)。 这个答案值得一读;它提供了全面的解释(我不会尝试复制!)。

但是,由于这可能很难理解,这里是使用您的代码的一种解决方案(playground ):

package main

import (
    "context"
    "fmt"
    "time"

    "golang.org/x/sync/errgroup"
)

func main() {
    const threads = 3

    ch := make(chan int, threads)

    eg, ctx := errgroup.WithContext(context.Background())
    for i := 0; i < threads; i++ {
        i := i
        eg.Go(func() error {
            fmt.Printf("Thread %d: STARTED\n", i)
            for n := range ch {
                fmt.Printf("Thread %d: GOT=%d\n", i, n)
                time.Sleep(time.Duration(1) * time.Second)
                // Simulate failed thread
                if n == 2 {
                    fmt.Printf("Thread %d: FAILED\n", i)
                    return fmt.Errorf("Thread %d: FAILED", i)
                }
                // For the purpose of this example we will just check the context after
                // doing the work.
                if ctx.Err() != nil {
                    fmt.Printf("Thread %d: Quiting due to context\n", i)
                    return fmt.Errorf("Thread %d: Context cancelled: ", i)
                }
            }
            return nil
        })
    }

    // We want to stop sending new work if there is a failure (otherwise `ch <- i` will block permanently);
sendLoop:
    for i := 0; i < 9; i++ {
        select {
        case ch <- i:
        case <-ctx.Done():
            fmt.Printf("stopped\n")
            break sendLoop // Just exit the loop if something goes wrong (you may want to do something else here)
        }
    }
    close(ch) // Note: Important that this happens even if there is an error (otherwise `for n := range ch` may block, leaking goroutines)
    fmt.Printf("all sent\n")
    if err := eg.Wait(); err != nil {
        panic(err)
    }
}

以上就是如何在错误时停止从通道读取?的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: 如何在错误时停止从通道读取?

本文链接: https://lsjlt.com/news/562592.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作