对于这个用例,它似乎可能是有效的: 这是简单的代码,但你应该明白 -
func Log(v interface{}){
1. get json - json marshal some large object v
2. write big buf to a file
}
上面的代码可能会非常阻塞,所以也许想放入一个 goroutine:
func Log(v interface{}){
go func(){
1. get json - json marshal some large object v
2. write big buf to a file (not necessarily stdout)
}()
}
但问题是我们在这里创建了很多 goroutine,这可能会违背将其放入 goroutine 的目的。
所以我的问题是 - 有没有办法以某种方式使用 goroutine 池,并使用它们。即使 10 个人在一个泳池里就已经很棒了。
我假设使用渠道与他们沟通,但不确定具体如何
两个规定:
Prelim、非测试工作池,具有以下功能:
请戳个洞,我确信锁定不太正确
package pool
import "sync"
type Worker struct {
c chan func()
mtx sync.Mutex
isBusy bool
}
type Pool struct {
mtx *sync.Mutex
Size int
workers []*Worker
Count int
RoundRobinCounter int
}
func (p *Pool) createWorkers() {
for i := 0; i < p.Size; i++ {
var w = &Worker{
c: make(chan func(), 1),
mtx: sync.Mutex{},
isBusy: false,
}
go func(v chan func()) {
for {
var f = <-v
w.mtx.Lock()
w.isBusy = true
p.Count++
f()
p.Count--
w.isBusy = false
w.mtx.Unlock()
}
}(c)
p.workers = append(p.workers)
}
}
func CreatePool(size int) *Pool {
var p = &Pool{
Size: size,
Count: 0,
RoundRobinCounter: size + 1,
}
p.createWorkers()
return p
}
func (p *Pool) GoPool(z func()) {
p.mtx.Lock()
if p.Count >= p.Size {
p.mtx.Unlock()
// queue is full, so just create a new goroutine here
go z()
return
}
for _, v := range p.workers {
if !v.isBusy {
v.mtx.Lock()
p.mtx.Unlock()
v.isBusy = true
v.c <- z
v.mtx.Unlock()
return
}
}
p.mtx.Unlock()
// couldn't find a non-busy one, so just round robin to next
p.RoundRobinCounter = (p.RoundRobinCounter + 1) % p.Size
var v = p.workers[p.RoundRobinCounter]
v.mtx.Lock()
v.c <- z
v.mtx.Unlock()
}