首页 > 其他分享 >Golang sync包中errgroup的使用详解

Golang sync包中errgroup的使用详解

时间:2023-10-21 14:22:36浏览次数:33  
标签:包中 sending www http err url errgroup sync com

WaitGroup 主要用于控制任务组下的并发子任务。它的具体做法就是,子任务 goroutine 执行前通过 Add 方法添加任务数目,子任务 goroutine 结束时调用 Done 标记已完成任务数,主任务 goroutine 通过 Wait 方法等待所有的任务完成后才能执行后续逻辑

package main
  
 import (
     "net/http"
     "sync"
 )
  
 func main() {
    var wg sync.WaitGroup
    var urls = []string{
        "http://www.golang.org/",
        "http://www.baidu.com/",
        "http://www.bokeyuan12111.com/",
    }
    for _, url := range urls {
        wg.Add(1)
        go func(url string) {
            defer wg.Done()
            resp, err := http.Get(url)
            if err != nil {
                return
            }
            resp.Body.Close()
        }(url)
    }
    wg.Wait()
}

但在实际的项目代码中,子任务 goroutine 的执行并不总是顺风顺水,它们也许会产生 error。而 WaitGroup 并没有告诉我们在子 goroutine 发生错误时,如何将其抛给主任务 groutine。这个时候可以考虑使用 errgroup

package main
  
 import (
     "fmt"
     "net/http"
  
     "golang.org/x/sync/errgroup"
 )
  
func main() {
    var urls = []string{
        "http://www.golang.org/",
        "http://www.baidu.com/",
        "http://www.bokeyuan12111.com/",
    }
    g := new(errgroup.Group)
    for _, url := range urls {
        url := url
        g.Go(func() error {
            resp, err := http.Get(url)
            if err != nil {
                fmt.Println(err)
                return err
            }
            fmt.Printf("get [%s] success: [%d] \n", url, resp.StatusCode)
            return resp.Body.Close()
        })
    }
    if err := g.Wait(); err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("All success!")
    }
}

get [http://www.baidu.com/] success: [200]
Get "http://www.bokeyuan12111.com/": dial tcp: lookup www.bokeyuan12111.com: no such host
Get "http://www.golang.org/": dial tcp 142.251.42.241:80: i/o timeout
Get "http://www.bokeyuan12111.com/": dial tcp: lookup www.bokeyuan12111.com: no such host

errgroup 上下文取消

package main
 
import (
    "context"
    "fmt"
 
    "golang.org/x/sync/errgroup"
)
 
func main() {
 
    g, ctx := errgroup.WithContext(context.Background())
    dataChan := make(chan int, 20)
 
    // 数据生产端任务子 goroutine
    g.Go(func() error {
        defer close(dataChan)
        for i := 1; ; i++ {
            if i == 10 {
                return fmt.Errorf("data 10 is wrong")
            }
            dataChan <- i
            fmt.Println(fmt.Sprintf("sending %d", i))
        }
    })
 
    // 数据消费端任务子 goroutine
    for i := 0; i < 3; i++ {
        g.Go(func() error {
            for j := 1; ; j++ {
                select {
                case <-ctx.Done():
                    return ctx.Err()
                case number := <-dataChan:
                    fmt.Println(fmt.Sprintf("receiving %d", number))
                }
            }
        })
    }
 
    // 主任务 goroutine 等待 pipeline 结束数据流
    err := g.Wait()
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println("main goroutine done!")
}

sending 1
sending 2
sending 3
sending 4
sending 5
sending 6
sending 7
sending 8
sending 9
receiving 1
receiving 3
receiving 2
receiving 4
data 10 is wrong
main goroutine done!

标签:包中,sending,www,http,err,url,errgroup,sync,com
From: https://www.cnblogs.com/qcy-blog/p/17778905.html

相关文章

  • C# async await 异步执行方法
    代码如下usingSystem;usingSystem.Threading;usingSystem.Threading.Tasks;namespaceDemo{classProgram{staticvoidMain(string[]args){Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-ddHH:mm:ss&qu......
  • 在Java中,可以使用`java.nio.file`包中的`Files`类来进行文件搜索。以下是一种模糊搜索
    在Java中,可以使用`java.nio.file`包中的`Files`类来进行文件搜索。以下是一种模糊搜索文件的方法:```javaimportjava.io.IOException;importjava.nio.file.*;importjava.nio.file.attribute.BasicFileAttributes;publicclassFileSearch{publicstaticvoidmain(String......
  • async函数执行机制
    fn()console.log(1);setTimeout(()=>{console.log(4);},100);Promise.resolve().then(()=>{console.log(2);})console.log(3);functionfnPromise(){......
  • async和await
    https://blog.csdn.net/weixin_44228698/article/details/1087447621,await从线程池中获取线程执行。2,await后的代码从线程池中获取线程执行,与1中的线程号可能相同,也可能不同。3,UI线程执行async,await后的代码回到UI线程执行。4,获取返回结果.Result会阻塞当前线程,注意与3造成死......
  • 使用SyncFavor进行文件同步
    SyncFavor是基于C#开发的免费文件同步工具,运行在windows上,下载链接:https://github.com/bsmith-zhao/sync同步管理界面:批量运行界面: 主从同步示例 下载压缩包解压,双击sync.exe启动同步管理器,可以看到空白的管理界面:点击工具栏的[添加工作区]创建工作区,工作区是一系列......
  • Java Volatile和synchronized的区别,notify()和notifyAll()的区别
    JavaVolatile和synchronized的区别,notify()和notifyAll()的区别1.Volatile和synchronized的区别:(1)、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。(2)、volatile只能保证可见性和有序性,不能保证原子性。......
  • [Compose] Async programming: Thunks
    ThunksSyncthunk:Ablockerofcodewhichhaseverythingreadyandcanreturnthevaluedirectly.functionadd(x,y){returnx+y}constthunk=function(){returnadd(10,15)}thunk()//25Ao thunkisprettymuchthesameasHighorderfunc......
  • [Compose] Callback is not suitable for Async programming
    Anexampleofcallbackimplemnetationforhandlingasyncflow:functionfakeAjax(url,cb){varfake_responses={file1:"Thefirsttext",file2:"Themiddletext",file3:"Thelasttext",};varrandomDela......
  • 【Java 并发编程】synchronized
    synchronized关键字synchronized是Java中的一个关键字,翻译成中文是同步的意思,主要解决的是多个线程之间访问资源的同步性,可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。使用方法修饰实例方法给当前对象实例加锁,进入同步代码前要获得当前对象实例的锁......
  • js Promise、generator、async/await
    1.Promise的出现是为了解决ajax回调地狱的问题,但是Promise的链式调用看起来也不太美观。2.generator的出现就是为了让异步流程看起来更直观。3.然而generator在定义的时候是直观的,在执行的时候又会面临回调地狱的问题,所以async/await应运而生,async/await可以直接......