在ants中使用四种函数类型:有参数无返回值、带参数有返回值、无参数无返回值、无参数有返回值。
在 ants
库中,这些函数可以作为任务提交到协程池中进行并发处理。下面我会分别为每种函数类型写出如何在 ants
中使用的示例代码,并处理其中的 error
。
1. 有参数无返回值的函数(处理带参数且没有返回值的任务)
对于这种类型的函数,可以通过 pool.Submit()
提交任务,并确保函数的执行没有返回值。
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
)
// 有参数无返回值的函数
func processTask(taskID int) error {
if taskID%2 == 0 {
return fmt.Errorf("task %d failed", taskID) // 偶数任务失败
}
fmt.Printf("Processing task %d\n", taskID)
return nil
}
func main() {
// 创建一个最大并发数为 5 的协程池
pool, err := ants.NewPool(5)
if err != nil {
log.Fatalf("Failed to create pool: %v", err)
}
defer pool.Release() // 程序退出时,释放池资源
// 提交有参数无返回值的任务
for i := 0; i < 10; i++ {
i := i // 注意捕获局部变量
err := pool.Submit(func() {
err := processTask(i)
if err != nil {
fmt.Printf("Error processing task %d: %v\n", i, err)
}
})
if err != nil {
log.Printf("Failed to submit task %d: %v", i, err)
}
}
// 等待池中的任务完成
pool.Wait()
}
2. 带参数有返回值的函数(处理带参数且有返回值的任务)
对于这种类型的函数,你可以使用 pool.Invoke()
提交任务并获取返回值。需要注意的是,Invoke
返回的是一个 interface{}
类型的结果,需要类型断言来使用。
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
)
// 带参数有返回值的函数
func calculateSum(a, b int) (int, error) {
if a < 0 || b < 0 {
return 0, fmt.Errorf("both numbers must be non-negative")
}
return a + b, nil
}
func main() {
// 创建一个最大并发数为 5 的协程池
pool, err := ants.NewPoolWithFunc(5, func(i interface{}) (interface{}, error) {
params := i.([]int)
return calculateSum(params[0], params[1])
})
if err != nil {
log.Fatalf("Failed to create pool: %v", err)
}
defer pool.Release() // 程序退出时,释放池资源
// 提交带参数有返回值的任务
for i := 0; i < 5; i++ {
params := []int{i, i + 1}
result, err := pool.Invoke(params)
if err != nil {
log.Printf("Error processing task %d: %v", i, err)
continue
}
fmt.Printf("Result for task %d: %v\n", i, result)
}
// 等待池中的任务完成
pool.Wait()
}
3. 无参数无返回值的函数(处理无参数且无返回值的任务)
对于这种类型的函数,任务不接受任何输入参数,并且不返回值。你可以使用 pool.Submit()
来提交这类任务。
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
)
// 无参数无返回值的函数
func doSomething() error {
// 模拟耗时任务
fmt.Println("Doing something...")
return nil
}
func main() {
// 创建一个最大并发数为 5 的协程池
pool, err := ants.NewPool(5)
if err != nil {
log.Fatalf("Failed to create pool: %v", err)
}
defer pool.Release() // 程序退出时,释放池资源
// 提交无参数无返回值的任务
for i := 0; i < 5; i++ {
err := pool.Submit(func() {
err := doSomething()
if err != nil {
fmt.Printf("Error executing task: %v\n", err)
}
})
if err != nil {
log.Printf("Failed to submit task %d: %v", i, err)
}
}
// 等待池中的任务完成
pool.Wait()
}
4. 无参数有返回值的函数(处理无参数且有返回值的任务)
对于这种类型的函数,你可以使用 pool.Invoke()
来提交任务,并返回结果。返回值可以直接用 Invoke
方法获取。
package main
import (
"fmt"
"github.com/panjf2000/ants/v2"
"log"
)
// 无参数有返回值的函数
func getGreeting() (string, error) {
// 模拟一个耗时任务
return "Hello from the goroutine!", nil
}
func main() {
// 创建一个最大并发数为 5 的协程池
pool, err := ants.NewPoolWithFunc(5, func(i interface{}) (interface{}, error) {
return getGreeting()
})
if err != nil {
log.Fatalf("Failed to create pool: %v", err)
}
defer pool.Release() // 程序退出时,释放池资源
// 提交无参数有返回值的任务
for i := 0; i < 5; i++ {
result, err := pool.Invoke(nil) // 不传递参数
if err != nil {
log.Printf("Error processing task %d: %v", i, err)
continue
}
fmt.Printf("Result for task %d: %v\n", i, result)
}
// 等待池中的任务完成
pool.Wait()
}
结论
Submit()
方法适用于无返回值的任务,无论是有参数还是无参数。Invoke()
方法适用于有返回值的任务,支持带参数和无参数的情况。- 错误处理:在每个任务执行过程中,通过
error
进行错误管理,确保任务失败时能够及时响应。
通过这些示例,你可以根据你的任务类型使用 ants
来管理并发执行,同时处理每种情况中的错误。