欢迎来到GoPool,这是一个95%的代码由GPT生成的项目。你可以在pro.devchat.ai找到相应的提交和提示列表。
GoPool是一个高性能、功能丰富且易于使用的Golang工作池库。它旨在管理和回收一组goroutine以并发完成任务,提高应用程序的效率和性能。
性能测试
这个表格展示了三个Go库的性能测试结果:GoPool、ants和pond。表格包括每个库处理100万个任务所需的时间和内存消耗(MB)。
你可以运行以下命令在你的机器上测试GoPool、ants和pond的性能:
$ go test -benchmem -run=^$ -bench ^BenchmarkGoPoolWithMutex$ github.com/devchat-ai/gopool
$ go test -benchmem -run=^$ -bench ^BenchmarkAnts$ github.com/devchat-ai/gopool
$ go test -benchmem -run=^$ -bench ^BenchmarkPond$ github.com/devchat-ai/gopool
在我的机器上进行性能测试的结果如下:
- GoPool
go test -benchmem -run=^$ -bench ^BenchmarkGoPool$ github.com/devchat-ai/gopool
goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN BenchmarkGoPool
BenchmarkGoPool
BenchmarkGoPool-10 1 1131749792 ns/op 2212096 B/op 17447 allocs/op
PASS
ok github.com/devchat-ai/gopool 1.342s
- ants
go test -benchmem -run=^$ -bench ^BenchmarkAnts$ github.com/devchat-ai/gopool
goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN BenchmarkAnts
BenchmarkAnts
BenchmarkAnts-10 1 1429439750 ns/op 9369552 B/op 70259 allocs/op
PASS
ok github.com/devchat-ai/gopool 1.681s
- pond
go test -benchmem -run=^$ -bench ^BenchmarkPond$ github.com/devchat-ai/gopool
goos: darwin
goarch: arm64
pkg: github.com/devchat-ai/gopool
=== RUN BenchmarkPond
BenchmarkPond
BenchmarkPond-10 1 3322063917 ns/op 2310840 B/op 21325 allocs/op
PASS
ok github.com/devchat-ai/gopool 3.541s
特性
-
任务队列:GoPool使用线程安全的任务队列来存储等待处理的任务。多个工作者可以同时从这个队列中获取任务。任务队列的大小可以配置。
-
并发控制:GoPool可以控制并发任务的数量,防止系统过载。
-
动态工作者调整:GoPool可以根据任务数量和系统负载动态调整工作者的数量。
-
优雅关闭:GoPool可以优雅地关闭。当没有更多任务或收到关闭信号时,它会停止接受新任务,并等待所有正在进行的任务完成后再关闭。
-
任务错误处理:GoPool可以处理任务执行过程中发生的错误。
-
任务超时处理:GoPool可以处理任务执行超时。如果任务在指定的超时时间内未完成,该任务被视为失败并返回超时错误。
-
任务结果获取:GoPool提供了一种获取任务结果的方法。
-
任务重试:GoPool为失败的任务提供重试机制。
-
锁定制化:GoPool支持不同类型的锁。你可以使用内置的
sync.Mutex
或自定义锁,如spinlock.SpinLock
。 -
任务优先级:GoPool支持任务优先级。优先级较高的任务会先被处理。
安装
要安装GoPool,使用go get
:
go get -u github.com/devchat-ai/gopool
使用
这里是一个使用sync.Mutex
的GoPool简单示例:
package main
import (
"sync"
"time"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100)
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error){
time.Sleep(10 * time.Millisecond)
return nil, nil
})
}
pool.Wait()
}
这里是如何使用spinlock.SpinLock
的GoPool示例:
package main
import (
"time"
"github.com/daniel-hutao/spinlock"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithLock(new(spinlock.SpinLock)))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error){
time.Sleep(10 * time.Millisecond)
return nil, nil
})
}
pool.Wait()
}
可配置的任务队列大小
GoPool使用线程安全的任务队列来存储等待处理的任务。多个工作者可以同时从这个队列中获取任务。在创建池时,可以使用WithTaskQueueSize
选项配置任务队列的大小。
以下是使用可配置任务队列大小的GoPool示例:
package main
import (
"time"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithTaskQueueSize(5000))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error){
time.Sleep(10 * time.Millisecond)
return nil, nil
})
}
pool.Wait()
}
动态工作者调整
GoPool 支持动态工作者调整。这意味着池中的工作者数量可以根据队列中的任务数量增加或减少。通过在创建池时设置 MinWorkers 选项可以启用此功能。
以下是使用动态工作者调整的 GoPool 示例:
package main
import (
"time"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithMinWorkers(50))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error){
time.Sleep(10 * time.Millisecond)
return nil, nil
})
}
pool.Wait()
}
在此示例中,池初始有 50 个工作者。如果队列中的任务数量超过当前工作者数量的 3/4,且当前工作者数量小于 MaxWorkers,池将会将工作者数量翻倍,直到达到 MaxWorkers。如果队列中的任务数量为零,且当前工作者数量大于 MinWorkers,池将会将工作者数量减半,直到达到 MinWorkers。
任务超时处理
GoPool 支持任务超时。如果一个任务的执行时间超过指定的超时时间,它将被取消。通过在创建池时设置 WithTimeout
选项可以启用此功能。
以下是使用任务超时的 GoPool 示例:
package main
import (
"time"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithTimeout(1*time.Second))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error) {
time.Sleep(2 * time.Second)
return nil, nil
})
}
pool.Wait()
}
在此示例中,如果任务执行时间超过 1 秒,它将被取消。
任务错误处理
GoPool 支持任务错误处理。如果任务返回错误,将调用错误回调函数。通过在创建池时设置 WithErrorCallback
选项可以启用此功能。
以下是使用错误处理的 GoPool 示例:
package main
import (
"errors"
"fmt"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithErrorCallback(func(err error) {
fmt.Println("任务错误:", err)
}))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error) {
return nil, errors.New("任务错误")
})
}
pool.Wait()
}
在此示例中,如果任务返回错误,错误将被打印到控制台。
任务结果获取
GoPool 支持任务结果获取。如果任务返回结果,将调用结果回调函数。通过在创建池时设置 WithResultCallback
选项可以启用此功能。
以下是使用任务结果获取的 GoPool 示例:
package main
import (
"fmt"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithResultCallback(func(result interface{}) {
fmt.Println("任务结果:", result)
}))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error) {
return "任务结果", nil
})
}
pool.Wait()
}
在此示例中,如果任务返回结果,结果将被打印到控制台。
任务重试
GoPool 支持任务重试。如果任务失败,它可以被重试指定的次数。通过在创建池时设置 WithRetryCount
选项可以启用此功能。
以下是使用任务重试的 GoPool 示例:
package main
import (
"errors"
"fmt"
"github.com/devchat-ai/gopool"
)
func main() {
pool := gopool.NewGoPool(100, gopool.WithRetryCount(3))
defer pool.Release()
for i := 0; i < 1000; i++ {
pool.AddTask(func() (interface{}, error) {
return nil, errors.New("任务错误")
})
}
pool.Wait()
}
在此示例中,如果任务失败,它将被重试最多 3 次。