-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultirun.go
58 lines (48 loc) · 1.28 KB
/
multirun.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//Package multirun is a quick and easy package to run a batch task on multiple goroutines
package multirun
import (
"reflect"
"runtime"
"sync"
)
//DefaultGoroutines is the default number of goroutines to use
var DefaultGoroutines int
//Runnable is an interface for any runnable task type
type Runnable interface {
Run(int)
}
type simpleRunnable func(int)
func (r simpleRunnable) Run(iter int) {
r(iter)
}
//SimpleRunnable creates a simple runnable with a function that takes a sequential number
func SimpleRunnable(task func(int)) Runnable {
return simpleRunnable(task)
}
func runLoop(work <-chan int, locker *sync.RWMutex, r Runnable) {
locker.RLock()
defer locker.RUnlock()
for i := range work {
r.Run(i)
}
}
//Run runs a task in parallell
func Run(r Runnable, count int, goroutines int) {
work := make(chan int)
locker := new(sync.RWMutex)
for ; goroutines > 0; goroutines-- { //Start runners
go runLoop(work, locker, r)
}
for count--; count > -1; count-- { //Distribute work
work <- count
}
close(work)
locker.Lock() //Wait for everything to finish
}
//Array iterates over an array in parallell
func Array(arr interface{}, task func(int)) {
Run(SimpleRunnable(task), reflect.ValueOf(arr).Len(), DefaultGoroutines)
}
func init() {
DefaultGoroutines = runtime.NumCPU()
}