Skip to content

Instantly share code, notes, and snippets.

@tobgu
Created August 17, 2016 15:31
Show Gist options
  • Save tobgu/4437525bad8857b1581252e433aa5384 to your computer and use it in GitHub Desktop.
Save tobgu/4437525bad8857b1581252e433aa5384 to your computer and use it in GitHub Desktop.
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