Skip to content

Instantly share code, notes, and snippets.

@r3code
Forked from unanoc/goroutinesLimit.go
Created April 19, 2020 09:21
Show Gist options
  • Save r3code/ecb0ad8d92866defa98ccdbd7ea78af7 to your computer and use it in GitHub Desktop.
Save r3code/ecb0ad8d92866defa98ccdbd7ea78af7 to your computer and use it in GitHub Desktop.
Ограничение горутин по ресурсам. А именно, чтобы в одно время работало не больше определенного количества горутин.
package main
import (
"fmt"
"runtime"
"strings"
"sync"
"time"
)
const (
goroutineCount = 5
iterationCount = 6
quotaCount = 2 // количество горутин, которые должны работать, пока остальные будут ждать их завершения
)
func worker(in int, wg *sync.WaitGroup, quotaChan chan struct{}) {
quotaChan <- struct{}{} // занимаем слот в канале. Если места не будет, то горутина будет ждать и не начнет работу, пока не освободиться место
defer wg.Done()
for j := 0; j < iterationCount; j++ {
fmt.Printf(formatWork(in, j))
if j%2 == 0 {
<-quotaChan // делимся ресурсами с другими горутинами
quotaChan <- struct{}{} // но при этом лимит работащих горутин по прежнему тот же
}
runtime.Gosched() // передает управление другой горутине
}
<-quotaChan // освобождает слот
}
func main() {
wg := &sync.WaitGroup{}
quotaChan := make(chan struct{}, quotaCount) // буфферезированный канал(асинхронный), с пустыми структурами(они не занимают места в памяти)
for i := 0; i < goroutineCount; i++ {
wg.Add(1)
go worker(i, wg, quotaChan)
}
time.Sleep(time.Millisecond)
wg.Wait()
}
func formatWork(in, j int) string {
return fmt.Sprintln(strings.Repeat(" ", in), "█",
strings.Repeat(" ", goroutineCount-in),
"th", in,
"iter", j, strings.Repeat("■", j))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment