Created
August 18, 2020 04:47
-
-
Save santosh/b53c4925b1e45e9a00f2b128c991aee6 to your computer and use it in GitHub Desktop.
Worker pool with buffered channel.
This file contains hidden or 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 ( | |
"fmt" | |
"math/rand" | |
"sync" | |
"time" | |
) | |
// Worker pool is a collection of threads which are waiting | |
// for tasks to be assigned to them. | |
// Once they finish the task assigned, | |
// they make themselves available again for the next task. | |
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 main() { | |
startTime := time.Now() | |
noOfJobs := 100 | |
go allocate(noOfJobs) | |
done := make(chan bool) | |
go result(done) | |
noOfWorkers := 20 | |
createWorkerPool(noOfWorkers) | |
<-done | |
endTime := time.Now() | |
diff := endTime.Sub(startTime) | |
fmt.Println("total time taken", diff.Seconds(), "seconds") | |
} | |
// digits calculate sum of the digit in a number | |
func digits(number int) int { | |
sum := 0 | |
no := number | |
for no != 0 { | |
digit := no % 10 | |
sum += digit | |
no /= 10 | |
} | |
time.Sleep(2 * time.Second) | |
return sum | |
} | |
// worker takes one job at a time from jobs, does the the calculation, | |
// wraps the output in a Result and pushes to results channel | |
func worker(wg *sync.WaitGroup) { | |
for job := range jobs { | |
output := Result{job, digits(job.randomno)} | |
results <- output | |
} | |
wg.Done() | |
} | |
// createWorkerPool creates noOfWorkers number of workers | |
func createWorkerPool(noOfWorkers int) { | |
var wg sync.WaitGroup | |
for i := 0; i < noOfWorkers; i++ { | |
wg.Add(1) | |
go worker(&wg) | |
} | |
wg.Wait() | |
close(results) | |
} | |
// allocate gives one job at a time ot the jobs channel | |
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 no %d, sum of digits %d\n", result.job.id, result.job.randomno, result.sumofdigits) | |
} | |
done <- true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment