Created
December 14, 2022 09:43
-
-
Save nizhib/5ac7a8c9b24121b405cae24e8c95e97f to your computer and use it in GitHub Desktop.
Synchronizing workers with critical parts
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
package main | |
import ( | |
"log" | |
"math/rand" | |
"os" | |
"os/signal" | |
"sync" | |
"time" | |
) | |
func randomDuration() time.Duration { | |
return time.Duration(1000+rand.Int63n(1000)) * time.Millisecond | |
} | |
func work(job int, done <-chan struct{}, busy *sync.WaitGroup) { | |
log.Println("downloading", job) | |
time.Sleep(randomDuration()) | |
log.Println("processing", job) | |
time.Sleep(randomDuration()) | |
select { | |
case <-done: | |
log.Println("skipping", job) | |
return | |
default: | |
busy.Add(1) | |
log.Println("saving", job) | |
time.Sleep(randomDuration()) | |
busy.Done() | |
} | |
} | |
func run(jobs <-chan int, done <-chan struct{}, busy *sync.WaitGroup) { | |
for job := range jobs { | |
select { | |
case <-done: | |
return | |
default: | |
work(job, done, busy) | |
} | |
} | |
} | |
func main() { | |
workerCount := 4 | |
var wg sync.WaitGroup | |
interrupt := make(chan os.Signal, 1) | |
signal.Notify(interrupt, os.Interrupt) | |
defer func() { | |
signal.Stop(interrupt) | |
}() | |
done := make(chan struct{}, 1) | |
var busy sync.WaitGroup | |
go func() { | |
select { | |
case <-interrupt: | |
close(done) | |
signal.Stop(interrupt) | |
log.Println("busy wait") | |
busy.Wait() | |
log.Println("busy done") | |
os.Exit(0) | |
} | |
}() | |
jobs := make(chan int, workerCount) | |
log.Println("spawning the workers") | |
wg.Add(workerCount) | |
for i := 0; i < workerCount; i++ { | |
go func() { | |
defer wg.Done() | |
run(jobs, done, &busy) | |
}() | |
} | |
log.Println("spawning the jobs source") | |
go func() { | |
for job := 0; job < 3*workerCount; job++ { | |
jobs <- job | |
} | |
close(jobs) | |
}() | |
log.Println("waiting for the workers") | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment