go - Go 是否提供与 Threadpool 等效的功能
问题描述
我来自 Java/Scala,最近开始使用 Go。在 Java/Scala 中,线程池非常普遍,它们至少有 4 个不同的原因被使用。
- 重用工人已经实例化
- 资源管理。当我们有多个线程池时,我们可以确保如果系统的某个部分发生突发事件,它不会阻止其他部分运行。
- 自定义我们想要的调度类型(fork/join、classic、scheduled 等......)
- 自定义拒绝策略。
由于 Goroutine 很轻1是不需要的,即使提供一个也很好,我们可以创建某种工作池,而不需要太多麻烦来解决2。
但是,我觉得在 Go 中我们无法处理3和4。
是因为不需要它还是只是缺少功能?
解决方案
正如您所猜到的,由于 (1) 在 Go 中基本上不是问题,因此对线程/工作池的需求要少得多。(2) 也可以使用速率限制和资源信号量等技术来解决。至于 (3),Go 运行时会执行 goroutine 调度,因此自定义它并不容易,也不是惯用的。
也就是说,线程/工作池在 Go 中非常容易实现。这是gobyexample的一个简单示例:
// In this example we'll look at how to implement
// a _worker pool_ using goroutines and channels.
package main
import "fmt"
import "time"
// Here's the worker, of which we'll run several
// concurrent instances. These workers will receive
// work on the `jobs` channel and send the corresponding
// results on `results`. We'll sleep a second per job to
// simulate an expensive task.
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}
func main() {
// In order to use our pool of workers we need to send
// them work and collect their results. We make 2
// channels for this.
jobs := make(chan int, 100)
results := make(chan int, 100)
// This starts up 3 workers, initially blocked
// because there are no jobs yet.
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Here we send 5 `jobs` and then `close` that
// channel to indicate that's all the work we have.
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// Finally we collect all the results of the work.
// This also ensures that the worker goroutines have
// finished. An alternative way to wait for multiple
// goroutines is to use a [WaitGroup](waitgroups).
for a := 1; a <= 5; a++ {
<-results
}
}
如果你谷歌一下,你会发现一堆 3rd-party 包为各种用途实现了这种模式。正如您可能猜到的那样,没有单一的最佳方法可以做到这一点,因此您将选择对您的特定用例重要的任何方法。
推荐阅读
- r - 更改 R data.frame 某些月份的变量值?
- azure - Azure Pipelines 环境和 Helm
- python-3.x - 如何从 Tkinter wigets 使用的无用信息中清除 RAM 内存?
- reactjs - Facebook API:如何获取用户的广告帐户 ID?
- image - ValueError:无法确定区域大小;使用 4 件箱
- r - 使用 ImputeTS 进行多变量时间序列预测?
- jmeter - 如何使用 Jmeter 阅读 Gmail 中的最新电子邮件?
- kubernetes - Kubernetes 中的网络策略在不同的命名空间中不起作用
- r - 停止“应用”将矩阵转换为 R 中的向量?
- ios - iOS 14.2 中引入 AudioToolback 崩溃