
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)
}
}以上就是如何在错误时停止从通道读取?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号