Challenge 1 - Scheduler
- Go course
- Expert
- Lesson 31/34
- 8 min
Write a monitoring tool that inspects goroutine behavior.
Challenge: bounded parallelism
You will write a program that processes 1000 jobs, but at most GOMAXPROCS jobs may run at once. Spawning unbounded goroutines strains the scheduler and memory; a fixed number of workers uses the CPU fully.
isler := make(chan int)
sonuc := make(chan int)
for w := 0; w < runtime.GOMAXPROCS(0); w++ {
go isci(isler, sonuc)
}Workers take jobs with for i := range isler and finish when the channel closes.
Plan
1) Start n workers with wg.Add(n). 2) A goroutine sends 1..1000 to isler and closes it. 3) Another goroutine does close(sonuc) after wg.Wait(). 4) main sums with for r := range sonuc. Each worker sends the square of its number; the expected total is 333,833,500.
Practice Worker pool
Write the pool following the plan and print the sum of squares.
Starter code
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
// buraya yaz
}Sample solution
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
isler := make(chan int)
sonuc := make(chan int)
n := runtime.GOMAXPROCS(0)
var wg sync.WaitGroup
wg.Add(n)
for w := 0; w < n; w++ {
go func() {
defer wg.Done()
for i := range isler {
sonuc <- i * i
}
}()
}
go func() {
for i := 1; i <= 1000; i++ {
isler <- i
}
close(isler)
}()
go func() {
wg.Wait()
close(sonuc)
}()
toplam := 0
for r := range sonuc {
toplam += r
}
fmt.Println(toplam)
}Expected output
333833500
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Who should close the result channel, and when?
- main, as soon as it sends the jobs
- It should never be closed
- A separate goroutine, after all workers finish (after the WaitGroup wait) Correct answer
- Each worker when its job ends
Explanation: With several senders, if one worker closes the channel the others write to a closed channel and panic; it is closed after all senders are done.
2 Close the results
go func() {
wg.____()
close(sonuc)
}()
go func() {
wg.Wait()
close(sonuc)
}()
Explanation: wg.Wait blocks until all workers call Done; only then can the result channel be closed safely.
3 Piece and role
| Term | Meaning |
|---|---|
The isler channel |
Job distribution |
GOMAXPROCS(0) workers |
Parallelism bound |
wg.Wait + close |
Safe close |
range sonuc |
Collecting |