Created
August 17, 2016 15:31
-
-
Save tobgu/4437525bad8857b1581252e433aa5384 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"sync" | |
"fmt" | |
) | |
const MAX_CONCURRENCY = 40 | |
const NUMBER_OF_JOBS = 1000000 | |
func main() { | |
// runSemCh() | |
// runCondition() | |
runReuseGoRoutine() | |
} | |
func runReuseGoRoutine() { | |
// Currently about twice as slow as the other solutions | |
// (which are more or less on pair). Profiling needed | |
// to tell why... pprof blockprofile??? | |
job := make(chan bool) | |
sem := make(chan bool, MAX_CONCURRENCY) | |
quit := make(chan bool) | |
for i := 0; i < MAX_CONCURRENCY; i++ { | |
go func(id int) { | |
for { | |
select { | |
case <-job: | |
// fmt.Println("Working", id) | |
<-sem | |
case <-quit: | |
fmt.Println("Quitting", id) | |
<- sem | |
return | |
} | |
} | |
}(i) | |
} | |
for i := 0; i < NUMBER_OF_JOBS; i++ { | |
sem <- true | |
job <- true | |
} | |
for i := 0; i < cap(sem); i++ { | |
sem <- true | |
quit <- true | |
sem <- true | |
} | |
} | |
func runSemCh() { | |
sem := make(chan bool, MAX_CONCURRENCY) | |
for i := 0; i < NUMBER_OF_JOBS; i++ { | |
sem <- true | |
go func() { | |
defer func() { <-sem }() | |
}() | |
} | |
for i := 0; i < cap(sem); i++ { | |
sem <- true | |
} | |
} | |
type Scheduler struct { | |
runningJobCount int | |
cond *sync.Cond | |
} | |
func runCondition() { | |
s := &Scheduler{ | |
cond: &sync.Cond{L: &sync.Mutex{}}, | |
} | |
for i := 0; i < 1000000; i++ { | |
s.cond.L.Lock() | |
for s.runningJobCount == MAX_CONCURRENCY { | |
s.cond.Wait() | |
} | |
s.cond.L.Unlock() | |
go func() { | |
s.cond.L.Lock() | |
s.runningJobCount-- | |
s.cond.L.Unlock() | |
s.cond.Signal() | |
}() | |
s.cond.L.Lock() | |
s.runningJobCount++ | |
s.cond.L.Unlock() | |
} | |
// Wait for all outstanding go routines to finish | |
s.cond.L.Lock() | |
for s.runningJobCount > 0 { | |
s.cond.Wait() | |
} | |
s.cond.L.Unlock() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment