Если я правильно понял, вы хотите, чтобы все процессы читали строки из одного файла.Я не рекомендую это, это немного грязно, и вам придется а) читать одни и те же части файла несколько раз или б) использовать блокировку / мьютекс или какой-то другой механизм, чтобы избежать этого.Это будет сложно и сложно отлаживать.
Я бы попросил главный процесс прочитать файл и назначить строки для пула подпроцессов.Вы можете использовать общую память, чтобы ускорить это и уменьшить потребность в копировании данных IPC;или используйте потоки.
Что касается примеров, я ответил на вопрос о разветвлении и IPC и дал фрагмент кода для примера функции, которая разветвляется и возвращает пару каналов для связи родитель-потомок.Позвольте мне посмотреть, что (...) здесь это = P Может ли popen () создавать двунаправленные трубы, такие как pipe () + fork ()?
edit Я продолжал думать об этом = P.Вот идея:
Иметь подпроцессы вызова основного процесса с чем-то похожим на то, что я показал в ссылке выше.
Каждый процесс начинается сотправка байта мастеру для оповещения о готовности и блокировка на read()
.
Пусть основной процесс прочитает строку из файла в буфер общей памяти и заблокируетselect()
на его дочерних каналах.
Когда select()
вернется, прочитайте один из байтов, сигнализирующих о готовности, и отправьте этому подпроцессу смещение строки в пространстве общей памяти.
Основной процесс повторяется (читает строку, блокирует при выборе, читает байт для использования события готовности и т. Д.)
дети обрабатывают строку любым нужным вам способом, а затем отправляют байт мастеру, чтобы еще раз сообщить о готовности.
(Вы можете избежать буфера общей памяти, если хотите, и отправитьлинии вниз по трубам, хотя это будет включать в себя постоянную dата-копирования.Если обработка каждой строки является вычислительно дорогой, это не будет иметь большого значения;но если строки требуют небольшой обработки, это может замедлить вас.)
Надеюсь, это поможет!
изменить 2 на основе комментариев Ньюбы:
Хорошо, поэтому нет общей памяти.Используйте вышеприведенную модель, только вместо того, чтобы отправлять по конвейеру смещение строки, считанной в пространстве общей памяти, отправляйте всю строку.Это может звучать для вас, как будто вы тратите время, когда вы можете просто прочитать его из файла, но, поверьте мне, это не так.Каналы на несколько порядков быстрее, чем чтение из обычных файлов на жестком диске, и если вы хотите, чтобы подпроцессы считывали непосредственно из файла, вы столкнетесь с проблемой, которую я указал в начале ответа.
Итак, главный процесс:
Создает подпроцессы, используя что-то вроде функции, которую я написал (ссылка выше), которая создает каналы для двунаправленной связи.
Чтениестрока из файла в буфер (частная, локальная, без общей памяти).
Теперь у вас есть данные, готовые для обработки.Вызовите select (), чтобы заблокировать все каналы, которые связывают вас с вашими подпроцессами.
Выберите любой из каналов, для которых имеются данные, прочитайте из него один байт и затем отправьте строкуВы ожидаете обработки в буфере вниз по соответствующему каналу (помните, у нас было по 2 на дочерний процесс, чтобы идти вверх, один - вниз).
Повторите с шага 2то есть прочитайте еще одну строку.
Дочерние процессы:
Когда они запускаются, в их распоряжении имеется канал для чтения и канал для записи.Отправьте байт по каналу записи, чтобы сообщить ведущему процессу, что вы готовы и ожидаете обработки данных (это единственный байт, который мы прочитали в шаге 4 выше).
Блокировать на read()
, ожидая, пока ведущий процесс (который знает, что вы готовы после шага 1) отправит вам данные для обработки.Продолжайте читать, пока не достигнете новой строки (вы сказали, что читали строки, верно?).Примечание. Я следую вашей модели, отправляя по одной строке каждому процессу за раз, вы можете отправить несколько строк, если хотите.
Обработка данных.
Вернитесь к шагу 1, то есть отправьте еще один байт, чтобы указать, что вы готовы к дополнительным данным.
Итак, простой протокол для назначения задач такому числу подпроцессов, какты хочешь.Может быть интересно запустить тест с 1 ребенком, n детьми (где n - количество ядер на вашем компьютере) и более чем с n детьми, и сравнить результаты.
Вот так, это был длинный ответ.Я очень надеюсь, что помог xD