tee
перенаправляет свой стандартный ввод в каждый указанный файл, а pee
делает то же самое, но для труб. Эти программы отправляют каждую строку своего стандартного ввода в каждый указанный файл / канал.
Однако я искал способ «сбалансировать загрузку» стандартного ввода для разных каналов, чтобы одна строка отправлялась на первый канал, другая строка - на второй и т. Д. Также было бы неплохо, если бы stdout каналов собирался в один поток.
Вариант использования - простое распараллеливание процессов, интенсивно использующих ЦП, которые работают построчно. Я делал sed
в файле размером 14 ГБ, и он мог бы работать намного быстрее, если бы я мог использовать несколько sed
процессы. Команда была такой:
pv infile | sed 's/something//' > outfile
Для распараллеливания лучше всего, если GNU parallel будет поддерживать эту функцию таким образом (составлял --demux-stdin
вариант):
pv infile | parallel -u -j4 --demux-stdin "sed 's/something//'" > outfile
Однако такого варианта нет и parallel
всегда использует свой стандартный ввод в качестве аргументов для команды, которую он вызывает, например xargs
. Я попробовал это, но это безнадежно медленно, и понятно почему:
pv infile | parallel -u -j4 "echo {} | sed 's/something//'" > outfile
Я просто хотел знать, есть ли другой способ сделать это (кроме самого написания кода). Если бы была «балансировка нагрузки» tee
(назовем это lee
), Я мог сделать это:
pv infile | lee >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile) >(sed 's/something//' >> outfile)
Не очень, поэтому я определенно предпочитаю что-то вроде накрашенного parallel
версия, но это тоже сработает.
Мы обсуждаем, как реализовать именно эту функцию в списке рассылки GNU Parallel прямо сейчас. http://lists.gnu.org/archive/html/parallel/2011-01/msg00001.html
Не стесняйтесь присоединяться: http://lists.gnu.org/mailman/listinfo/parallel
Теперь прототип готов к тестированию: http://lists.gnu.org/archive/html/parallel/2011-01/msg00015.html
Я бы посмотрел на реализацию этого в Perl с Параллель :: ForkManager. Вы можете выполнить разделение строк в скрипте, а затем передать полученные строки в процессы Parallel :: ForkManager. Использование run_on_finish
обратный вызов для сбора вывода. Очевидно, что для вашего примера sed вы могли бы просто выполнить текстовую операцию в perl и, возможно, использовать что-то вроде AnyEvent для обработки параллелизма.