Я запускаю цикл - 24 раза, который вызывает нисходящий поток, который не может обрабатывать всю работу, выполняемую одновременно порожденными go-процедурами, я хочу ограничить это таким образом, чтобы только определенное количество (3 или 4) go-процедуры казнят. Пример кода выглядит следующим образом, если кто-нибудь может указать мне правильный шаблон для выполнения, это будет большим подспорьем.
for i:=0; i<24; i++ {
go callSomeDownStream()
}
func callSomeDownStream(wg *sync.WaitGroup, queue chan struct{}) {
defer func() {
<-queue
wg.Done()
}()
// do something
}
func main() {
wg := sync.WaitGroup{}
queue := make(chan struct{}, 3)
for i := 0; i < 24; i++ {
queue <- struct{}{}
wg.Add(1)
go callSomeDownStream(&wg, queue)
}
wg.Wait()
close(queue)
}
@Para Вы имеете в виду, что порядок (queue<-,wg.Add) и (<-queue,wg.Done) должен быть сохранен? Я думаю, это хорошая привычка. Но не похоже, что в этом сценарии будет утечка?
спасибо, это работает, но принятый ответ намного проще для проблемы
Вы можете использовать канал пустых структур для управления количеством одновременных рабочих горутин.
const MAX_CONCURRENT_JOBS = 3
func main() {
waitChan := make(chan struct{}, MAX_CONCURRENT_JOBS)
for i:=0; i < 24; i++ {
waitChan <- struct{}{}
go func() {
callSomeDownStream()
<-waitChan
}()
}
}
@Arpit, обратите внимание, что в основном это замаскированный счетный семафор ;-)
<-queue
надо раньшеwg.Done()
,иначе чан может протечь