Здравствуйте! До этого никогда не писал параллельные вычисления. Столкнулся с задачей: есть огромный массив ссылок. Допустим, 10к штук. Их нужно обработать партиями, хотя бы по 10. По сути это парсер. Много читал про горутины, но не совсем понял как заставить их обрабатывать порциями такой большой массив. Спасибо заранее за ответы.
У буфера каналов ограничение в размер int, но под буфер аллокации происходят, поэтому max int, конечно, лучше не использовать, но 10 тысяч это немного. Это достаточно общий паттерн, его реализовать можно по-разному, например просто цикл на твои десять тысяч ссылок запустить и с помощью одного канала в n буфер контролировать кол-во одновременных горутин, вот грубый набросок:
maxGoroutines := 10
limit := make(chan struct{}, maxGoroutines)
links := []string{"123",...}
for _, link := range links {
limit <- struct{}{} // блокировка, пока нет "свободного" места для нового обработчика
go func(l string) {
worker(l) // твой парсер, если результат нужен - можешь возвращать его в другой канал с буфером 10 тоже и т.д.
<-limit
}(link)
}
Максим Власов, только 10к ссылок стоит не хранить в ОЗУ, а правильнее брать их из СУБД или файла пачками, скажем, по 200-1000. Тогда память будет расходоваться разумно, а не хранить тупо все ссылки в ОЗУ, как есть.
1. Взять с СУБД 200 ссылок
2. Кидать каждую в канал, в цикле.
И так повторять, пока не закончатся все ссылки.
По примеру worker pool выше, строка jobs := make(chan int, numJobs)означает, что пока при наполнении канала 5-ю числами, 6-е не сможет войти в канал и это будет блокировать программу до тех пор, пока из канала не заберут хотя бы 1 число.
То же самое будет и со ссылками. Поэтому, "читатель" канала должен быть достаточно шустрым и заносить результаты куда нужно.