Golang基于errgroup实现并发调用的方法
在Golang中,errgroup是一个非常好用的并发控制库,它允许我们创建一组goroutine并发执行一系列的任务并监控它们的运行情况。本文将介绍如何使用errgroup实现并发调用的方法。
一、准备工作
在使用errgroup前,我们需要先引入它的包:
import "golang.org/x/sync/errgroup"
二、基本使用
我们可以使用errgroup的Go方法启动一个goroutine,该方法会返回一个error类型的值,只有当我们所有的goroutine都执行成功时,该返回值才为nil。例如:
package main
import (
"fmt"
"golang.org/x/sync/errgroup"
)
func main() {
var g errgroup.Group
g.Go(func() error {
fmt.Println("Task One")
return nil
})
g.Go(func() error {
fmt.Println("Task Two")
return nil
})
err := g.Wait()
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("All tasks have been completed successfully!")
}
}
在上面的例子中,我们首先创建了一个errgroup.Group,然后启动了两个goroutine,每个goroutine都展示了一个字符串。最后,我们使用Wait方法等待所有goroutine执行完毕,并检查它们是否都执行成功。如果有一个goroutine返回非nil的error值,那么Wait方法会立即返回该错误。
三、示例说明
下面,我们将通过两个示例来讲解使用errgroup实现并发调用的方法。
1. 多个HTTP请求
我们可以使用errgroup并发发送多个HTTP请求,等待所有的请求返回后再统一处理结果。例如:
package main
import (
"fmt"
"net/http"
"golang.org/x/sync/errgroup"
)
func main() {
var g errgroup.Group
urls := []string{"http://www.baidu.com", "http://www.google.com", "http://www.qq.com"}
for _, url := range urls {
url := url // 将url变量复制一份到当前goroutine的局部变量中
g.Go(func() error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Printf("%s: status code %d\n", url, resp.StatusCode)
return nil
})
}
err := g.Wait()
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("All HTTP requests have been completed successfully!")
}
}
在上面的例子中,我们使用errgroup并发发送了3个HTTP请求,并等待它们返回。每个goroutine都发送一个HTTP请求并展示响应状态码。如果其中一个HTTP请求失败了,那么Wait方法会立即返回错误。
2. 多个MySQL查询
我们也可以使用errgroup实现并发的MySQL查询,例如:
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/go-sql-driver/mysql"
"golang.org/x/sync/errgroup"
)
func main() {
var g errgroup.Group
db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/test?charset=utf8mb4")
if err != nil {
fmt.Println("Error to open MySQL:", err)
}
ids := []int{1, 2, 3, 4, 5}
for _, id := range ids {
id := id // 将id变量复制一份到当前goroutine的局部变量中
g.Go(func() error {
rows, err := db.Query("SELECT name FROM users WHERE id=?", id)
if err != nil {
return err
}
defer rows.Close()
var name string
for rows.Next() {
if err := rows.Scan(&name); err != nil {
return err
}
}
fmt.Printf("User %d: %s\n", id, name)
return nil
})
}
err = g.Wait()
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("All MySQL queries have been completed successfully!")
}
}
在上面的例子中,我们使用errgroup并发地查询5个用户的名称,每个goroutine都查询一个用户的名称。如果其中一个查询失败了,那么Wait方法会立即返回错误。
结束语
通过本文的介绍,相信读者已经了解到如何使用errgroup实现并发调用的方法。使用errgroup可以让我们更加方便地控制并发,在多个goroutine间协调,提高代码的可读性和维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:golang基于errgroup实现并发调用的方法 - Python技术站