Этот код предоставляет пример способа распределения работы (поиск строк в документах) среди нескольких goRoutines. В основном, код запускается goroutines
и передает им документы для поиска по каналу.
Но почему бы не использовать массив строк напрямую?
Можно было бы использоватьстроковый массив и переменная (давайте назовем это count
), чтобы отследить, к какому элементу массива вы подходите. У вас будет такой код (немного затянутый, чтобы продемонстрировать точку):
for {
if count > len(docarray) {
break;
}
doc := docarray[count]
count++
// Process the document
}
Однако вы столкнетесь с проблемами синхронизации. Например, что произойдет, если две подпрограммы go (работающие на разных процессорных ядрах) получат if count > len(docarray)
одновременно? Без чего-либо, что могло бы предотвратить это, они оба могли бы в конечном итоге обработать один и тот же элемент в срезе (и, возможно, пропустить следующий элемент, потому что оба они запускают count++
).
Синхронизация процессов является сложной и проблемы могут быть очень сложнымиотлаживать. Использование каналов скрывает от вас большую часть этой сложности и повышает вероятность того, что ваш код будет работать должным образом (он не решает все проблемы; обратите внимание на использование atomic.AddInt64(&found, lFound)
в примере кода, чтобы предотвратить другую потенциальную проблему, которая может возникнуть в результатеодновременная запись нескольких переменных в переменную).