Go提供与Threadpool等效的功能吗

jer*_*mie -3 concurrency go threadpool goroutine

我来自Java / Scala,最近开始使用Go。在Java / Scala中,线程池非常普遍,并且至少有四个不同的原因将使用它们。

  1. 重用工人已经实例化
  2. 资源管理。当我们有多个线程池时,我们可以确保如果系统的某个部分中发生了突发,那么它不会阻止其他部分的运行。
  3. 自定义我们想要的计划类型(分叉/联接,经典,计划等)
  4. 自定义拒绝策略。

由于Goroutine是如此轻便,因此不需要1,即使提供一个很好,我们也可以创建某种类型的工作程序池而无需过多地麻烦解决2

但是,我觉得在Go中我们不能处理34

是因为不需要它还是仅仅是缺少功能?

Eli*_*sky 5

您已经猜到了,由于(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
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,如果您稍稍Google一下,就会发现一堆实现该模式以用于各种用途的第三方软件包。您可能会猜到,没有唯一的最佳方法,所以您将选择对您的特定用例重要的任何内容。