Pooling resources across multiple goroutines
Resource pooling is the traditional way to improve performance and save resources. Usually, it is worth pooling the resources with expensive initialization. The Golang standard library provides the skeleton structure for a resource pool, which is considered to be safe for multiple goroutines access. This recipe describes how to use it.
集中资源在多个概念
资源池是提高性能和节约资源的传统方法。通常,将资源与昂贵的初始化结合起来是值得的。Golang标准库提供了一个资源池的骨架结构,它被认为是多个共享通道安全的。这个食谱描述了如何使用它。
package main
import "sync"
import "fmt"
import "time"
type Worker struct {
id string
}
func (w *Worker) String() string {
return w.id
}
var globalCounter = 0
var pool = sync.Pool{
New: func() interface{} {
res := &Worker{fmt.Sprintf("%d", globalCounter)}
globalCounter++
return res
},
}
func main() {
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(idx int) {
// This code block is done only once
w := pool.Get().(*Worker)
fmt.Println("Got worker ID: " + w.String())
time.Sleep(time.Second)
pool.Put(w)
wg.Done()
}(i)
}
wg.Wait()
}
/*
Got worker ID: 0
Got worker ID: 0
Got worker ID: 0
Got worker ID: 0
Got worker ID: 4
Got worker ID: 5
Got worker ID: 7
Got worker ID: 6
Got worker ID: 4
Got worker ID: 0
The sync package contains the struct for pooling the resources. The Pool struct has the Get and Put method to retrieve and put the resource back to the pool. The Pool struct is considered to be safe for concurrent access.
While creating the Pool struct, the New field needs to be set. The New field is a no-argument function that should return the pointer to the pooled item. This function is then called in case the new object in the pool needs to be initialized.
Note from the logs of the preceding example, that the Worker is reused while returned to the pool. The important fact is that there shouldn't be any assumption related to the retrieved items by Get and returned items to Put method (like I've put three objects to pool just now, so there will be at least three available). This is mainly caused by the fact that that the idle items in a Pool could be automatically removed at any time.
The pooling of resources is usually worth it if the resource initialization is expensive. Still, the management of resources brings some additional cost.
同步包包含资源池的结构。池结构具有get和get方法来检索,并将资源返回到池中。对于并发访问,池结构被认为是安全的。
在创建池结构时,需要设置新字段。新字段是一个无参数函数,它应该返回指向集合项的指针。如果需要初始化池中的新对象,则调用这个函数。
从前一个实例的日志中得到的注释是,在返回到池中时,该人员被重用。重要的事实是,不应该有任何与get和返回项相关的任何假设来放置方法(比如我刚才把三个对象放在池中,所以至少有三个可用)。这主要是由于池中空闲项目可以在任何时候自动删除的事实造成的。
如果资源初始化是昂贵的,那么资源的汇集通常是值得的。然而,资源的管理带来了一些额外的成本。
*/