Каков наилучший способ параллельного выполнения задач в Ksh и Perl?
-
05-07-2019 - |
Вопрос
У меня есть большой проект C ++, который мне нужно построить на платформе, которая не имеет параллельного make (например, make -j в Linux). На сервере 6 процессоров, и я хочу сделать параллельную сборку вручную. Р>
Я могу создать такой список задач для примерно 300 объектных файлов. Я использую Makefile для проверки зависимостей и инкрементной сборки:
make -f Makefile obj1.o
make -f Makefile obj2.o
make -f Makefile obj3.o ...
Как бы я выполнил эти задачи параллельно, запустив не более 6 задач одновременно с использованием Ksh и Perl? (Java или Python недоступны :-()
Решение
В Perl вы должны посмотреть Parallel :: ForkManager . Вы можете сделать что-то вроде этого:
my @make_obj = qw(
obj1.o
obj2.o
obj3.o
...
);
my $fm = $pm = new Parallel::ForkManager(6);
foreach my $obj (@make_obj) {
$fm->start and next;
system("make -f Makefile $make_obj");
$fm->finish();
}
Другие советы
Альтернативой разветвлению является запуск каждой сборки в отдельном потоке.
use threads;
my $max_threads = 5;
my @targets = qw(obj1.o obj2.o obj3.o ...);
while(@targets) {
my $num_threads = threads->list(threads::running);
if( $num_threads < $max_threads ) {
my $target = shift @targets;
threads->create(sub { return system "make $target" });
}
}
Я, к сожалению, размахиваю руками двумя кусочками. Во-первых, это заставляет цикл бездействовать, пока поток не завершится. Я считаю, что это достигается с помощью cond_wait () от thread :: shared и переменной семафора.
Второй - получить возвращаемое значение из make, чтобы вы знали, что что-то не получилось, и остановить сборку. Для этого вам нужно будет присоединиться () к каждому потоку, чтобы получить результат system (), код завершения процесса.
Извините за поспешный ответ. Надеюсь, сообщество заполнит остальные.
У gnu make в HPUX нет флага -j?
http://hpux.connect.org.uk/ HPPD / HPUX / Gnu / сделать-3,81 /
Используя GNU Parallel, вы можете написать:
parallel -j6 make -f Makefile obj{}.o ::: {1..500}
10-секундная установка:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
Подробнее: http://www.gnu.org/software/parallel/parallel_tutorial .html https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1а> р>
Если операционная система правильно обрабатывает межпроцессорное взаимодействие и планирование, вы просто должны быть в состоянии превратить все замыслы в фоновые процессы, если нет взаимозависимостей.
Если они все независимы, я бы выполнил серию таких команд:
make -f Makefile obj1.o &
make -f Makefile obj2.o &
...
make -f Makefile objn.o &
При наличии зависимостей зафиксируйте их двойным амперсандом ( & amp; & amp;
), чтобы зависимый элемент не запустился до тех пор, пока не завершится его «родительский».
Я понимаю, что это не совсем то решение, которое вы запрашивали, но именно так я бы решил эту проблему:)