Вы упоминаете в комментарии, что
каждая программа читает файл, который должен быть закодирован
Но, конечно, файл - любой file - уже каким-то образом закодирован: как простой текст, возможно, или UTF-8 (поток байтов), возможно, собранный в единицы «строк». Или это может быть поток изображений, такой как файл MPEG, состоящий из некоторого количества кадров. Или это может быть база данных, состоящая из записей. Какой бы ни была форма input , она содержит какую-то базовую единицу c, которую вы могли бы подать в свой (пере) кодировщик.
Эта единица, какой бы она ни была, является разумное место, чтобы разделить работу. ( Насколько разумно, зависит от того, что это такое. См. Идею chunking ниже.)
Допустим, файл состоит из независимых строк: затем используйте scanner.Scan
читать их и передавать каждую строку в канал, который принимает строки. Выделите N, для некоторых N читатели, которые читают канал, по одной строке за раз:
ch := make(chan string)
for i := 0; i < n; i++ {
go readAndEncode(ch)
}
// later, or immediately:
for s := bufio.NewScanner(os.Stdin); s.Scan(); {
ch <- s.Text()
}
close(ch)
Если имеется 100 строк и 4 считывателя, первые четыре ch <- s.Text()
операции go быстрые и пятый делает паузу до тех пор, пока один из считывателей не закончит кодирование и не вернется к чтению канала.
Если отдельные строки слишком малы, возможно, вам следует прочитать «порцию» (например, 1 МБ ) вовремя. Если в конце чанка есть частичная строка, сделайте резервную копию или прочитайте больше, пока не получите целую строку. Затем отправьте весь блок данных.
Поскольку каналы копируют данных, вы можете вместо этого sh отправить ссылку на блок. 1 Это будет верно для любого большего блока данных. (Строки имеют тенденцию быть короткими, и издержки на их копирование обычно не очень велики по сравнению с издержками на использование каналов в первую очередь. Если ваши строки имеют тип string
, смотрите сноску.)
Если строка или кусок строки здесь не являются правильной единицей работы, выясните, что означает . Думайте о горутинах как о людях (или занятых маленьких сусликах), каждый из которых получает одну работу . Они могут зависеть от кого-то другого - другого человека или суслика - выполнять меньшую работу, какой бы она ни была; и наличие десяти человек, или сусликов, работающих над подзадачами, позволяет руководителю управлять ими. Если вам нужно проделать одну и ту же работу N раз, а N не безгранично, вы можете раскрутить N подпрограмм. Если N является потенциально неограниченным, выделите фиксированное число (возможно, на основе #cpus) и подайте их на работу через канал.
1 As Burak Сердар отмечает, что некоторые копии могут быть удалены автоматически: например, строки в действительности являются срезами только для чтения. Типы срезов состоят из трех частей: указатель (ссылка) на базовые данные, длина и емкость. Копирование фрагмента копирует эти три части, но не базовые данные. То же самое относится и к строкам: строковые заголовки пропускают емкость, поэтому при отправке строки через канал копируются только два слова заголовка. Следовательно, многие из очевидных и простых в кодировании способов разделения данных уже будут довольно эффективными.