3 ms·
Here's how I like to do it: https://play.golang.com/p/AB6exUIkNRg https://play.golang.com/p/AB6exUIkNRg Contents pasted below. package main import (
by andonisus 6y ago
Here's how I like to do it:
https://play.golang.com/p/AB6exUIkNRg https://play.golang.com/p/AB6exUIkNRg
Contents pasted below.
package main
import (
"fmt"
"sync"
)
func main() {
wg := &sync.WaitGroup{}
e := NewParallelExecutor(uint64(10))
for i := 0; i < 100; i++ {
wg.Add(1)
func(_i int) {
//make closure to capture i correctly
e.Submit(func() {
fmt.Println(_i)
wg.Done()
})
}(i)
}
wg.Wait()
fmt.Println("All done.")
}
type Executor interface {
Submit(func())
}
type parallelExecutor struct {
queue []func()
inCh chan func()
doneCh chan struct{}
}
func NewParallelExecutor(limit uint64) Executor {
pe := ¶llelExecutor{
queue: make([]func(), 0, limit),
inCh: make(chan func()),
doneCh: make(chan struct{}),
}
go func() {
running := uint64(0)
for {
select {
case <- pe.doneCh:
running -= 1
case f := <- pe.inCh:
pe.queue = append(pe.queue, f)
}
if len(pe.queue) > 0 && running < limit {
running += 1
fmt.Println(fmt.Sprintf("Goroutines in flight, waiting: %d | %d", running, len(pe.queue)))
f := pe.queue[0]
pe.queue = pe.queue[1:]
go func(_f func()) {
_f()
pe.doneCh <- struct{}{}
}(f)
}
}
}()
return pe
}
func (p *parallelExecutor) Submit(f func()) {
p.inCh <- f
}