Last active
July 5, 2020 07:07
-
-
Save jasonsalas/daed070b2e93b36fea1e0c5c827538f2 to your computer and use it in GitHub Desktop.
Using worker pools & buffered channels in Go
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
/* using worker pools & buffered channels in Go */ | |
// h/t: Naveen Ramanathan @ golangbot.com | |
// https://golangbot.com/buffered-channels-worker-pools/ | |
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"sync" | |
"time" | |
) | |
type Job struct { | |
id int | |
randomno int | |
} | |
type Result struct { | |
job Job | |
sumofdigits int | |
} | |
var jobs = make(chan Job, 10) | |
var results = make(chan Result, 10) | |
func digits(number int) int { | |
sum := 0 | |
no := number | |
for no != 0 { | |
digit := no % 10 | |
sum += digit | |
no /= 10 | |
} | |
time.Sleep(time.Second * 2) | |
return sum | |
} | |
func worker(wg *sync.WaitGroup) { | |
for job := range jobs { | |
output := Result{job, digits(job.randomno)} | |
results <- output | |
} | |
wg.Done() | |
} | |
func createWorkerPool(noOfWorkers int) { | |
var wg sync.WaitGroup | |
for i := 0; i < noOfWorkers; i++ { | |
wg.Add(1) | |
go worker(&wg) | |
} | |
wg.Wait() | |
close(results) | |
} | |
func allocate(noOfJobs int) { | |
for i := 0; i < noOfJobs; i++ { | |
randomno := rand.Intn(999) | |
job := Job{i, randomno} | |
jobs <- job | |
} | |
close(jobs) | |
} | |
func result(done chan bool) { | |
for result := range results { | |
fmt.Printf("Job id: %d | input random number: %d | sum of digits: %d\n", | |
result.job.id, result.job.randomno, result.sumofdigits) | |
} | |
done <- true | |
} | |
func main() { | |
startTime := time.Now() | |
noOfJobs := 100 | |
go allocate(noOfJobs) | |
done := make(chan bool) | |
go result(done) | |
noOfWorkers := 10 | |
createWorkerPool(noOfWorkers) | |
<-done | |
endTime := time.Now() | |
diff := endTime.Sub(startTime) | |
fmt.Println("total time taken: ", diff.Seconds(), "seconds") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment