Есть много способов сделать это.Вы можете принимать различные дизайнерские решения в зависимости от того, насколько быстрым, простым, элегантным или сверхмощным вы хотите, чтобы это было.Один из способов, заявленный Эндрю Финнеллом, состоит в том, чтобы каждый поток открыл файл и прочитал его полностью независимо.Теоретически это не очень хорошо, потому что вы делаете дорогой ввод-вывод дважды, но на практике это, вероятно, хорошо, потому что ОС, вероятно, кэшировала содержимое того, что считывание выполняется первым.Двойной ввод-вывод все еще дороже, чем в среднем, потому что он включает в себя множество ненужных системных вызовов, но опять же на практике это будет неактуально, если у вас нет очень большого файла.
Еще одна модель того, как это сделатькаждый поток имеет входную очередь или общую глобальную очередь.Основной поток читает файл и помещает каждую строку по очереди в очередь (и), и, возможно, основной дублируется как один из ваших рабочих потоков.Это более сложно, потому что доступ к очереди (ам) должен быть синхронизирован, или должна использоваться некоторая реализация очереди без блокировки.В случае общей глобальной очереди происходит меньшее дублирование данных, но теперь жизненный цикл этих данных более сложный.
Просто чтобы указать, как много способов сделать такую простую вещь можно сделать, вы можете пойти по пути переподготовки и сделать каждый поток общим.Вместо того чтобы помещать данные в очередь (и), вы помещаете как данные (или указатели на данные), так и указатели на функции и позволяете каждому потоку выполнять обратный вызов.Такая модель может показаться полезной, если вы планируете добавлять для вычислений гораздо больше, но хотите ограничить количество потоков, которые вы будете использовать.