Last active
September 24, 2020 21:09
-
-
Save matthewoestreich/b5f021cd525a909693d9af2c1ec34180 to your computer and use it in GitHub Desktop.
How to create and use worker pools - learning about goroutines + channels
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 | |
/** | |
* Each worker calculates fibonacci sequence for N int in order to show how worker pools can be utilized. | |
* | |
* Instructions: | |
* UNCOMMENT `DemoCreateSingleWorker()` OR `DemoCreateOneWorkerPerCPUCore()` | |
* FOR BEST RESULTS, ONLY UNCOMMENT ONE AT A TIME | |
* | |
* BE WARNED THIS CAN GET PRETTY INTENSE ON YOUR CPU AFTER LIKE 2 MIN | |
*/ | |
import ( | |
"fmt" | |
"runtime" | |
) | |
func main() { | |
totalJobs := 100 | |
jobsPipe := make(chan int, totalJobs) | |
resultsPipe := make(chan int, totalJobs) | |
DemoCreateSingleWorker(jobsPipe, resultsPipe, totalJobs) | |
// DemoCreateOneWorkerPerCPUCore(jobsPipe, resultsPipe, totalJobs) | |
} | |
// fibonacci implemented terribly | |
func fib(n int) int { | |
if n <= 1 { | |
return n | |
} | |
return fib(n-1) + fib(n-2) | |
} | |
// worker defines our worker func. as long as there is a job in the | |
// queue we continue to pick up the 'next' job | |
func worker(jobs <-chan int, results chan<- int) { | |
for n := range jobs { | |
results <- fib(n) | |
} | |
} | |
// fillQueue fills up our jobs channel | |
func fillQueue(jobs chan<- int, numJobs int) { | |
for i := 0; i < numJobs; i++ { | |
jobs <- i | |
} | |
} | |
// takeJobFromQueueAndDo takes a job off the 'stack' and invokes it (idk if that's proper terminology?) | |
func takeJobFromQueueAndDo(results <-chan int, numJobs int) { | |
for j := 0; j < numJobs; j++ { | |
fmt.Printf("Taking job %d\n", j) | |
fmt.Println(<-results) | |
} | |
} | |
// DemoCreateOneWorkerPerCPUCore creates as many workers as there are CPU cores on the current machine | |
func DemoCreateOneWorkerPerCPUCore(jobs chan int, results chan int, numJobs int) { | |
defer close(jobs) | |
// Create as many workers as there are CPU cores on the current machine | |
for i := 0; i < runtime.NumCPU(); i++ { | |
go worker(jobs, results) | |
} | |
fillQueue(jobs, numJobs) | |
takeJobFromQueueAndDo(results, numJobs) | |
} | |
// DemoCreateSingleWorker creates one worker to pick jobs off the queue | |
func DemoCreateSingleWorker(jobs chan int, results chan int, numJobs int) { | |
defer close(jobs) | |
go worker(jobs, results) | |
fillQueue(jobs, numJobs) | |
takeJobFromQueueAndDo(results, numJobs) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment