Каков наилучший способ параллельного выполнения задач в Ksh и Perl? - PullRequest
4 голосов
/ 29 октября 2008

У меня есть этот большой проект 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 недоступны :-()

Ответы [ 5 ]

5 голосов
/ 30 октября 2008

В 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();
}
4 голосов
/ 30 октября 2008

Альтернативой разветвлению является запуск каждой марки в отдельном потоке.

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" });
    }
}

Я, к сожалению, размахиваю руками двумя кусочками. Во-первых, это заставляет цикл бездействовать, пока поток не завершится. Я считаю, что это достигается с помощью thread :: shared cond_wait () и переменной семафора.

Второй - получить возвращаемое значение из make, чтобы вы знали, что-то не получилось, и остановить сборку. Для этого вам нужно присоединиться () к каждому потоку, чтобы получить результат system (), код завершения процесса.

Извините за поспешный ответ. Надеюсь, сообщество заполнит остальные.

3 голосов
/ 30 октября 2008

У gnu make в HPUX нет флага -j?

http://hpux.connect.org.uk/hppd/hpux/Gnu/make-3.81/

1 голос
/ 06 ноября 2013

Используя 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

0 голосов
/ 29 октября 2008

Если операционная система правильно обрабатывает межпроцессорное взаимодействие и планирование, вы просто должны быть в состоянии превратить все замыслы в фоновые процессы, если нет взаимозависимостей.

Если они все независимы, я бы выполнил серию таких команд:

make -f Makefile obj1.o &
make -f Makefile obj2.o &
...
make -f Makefile objn.o &

При наличии зависимостей заштрихуйте их двойным амперсандом (&&), чтобы зависимый элемент не запускался до тех пор, пока не завершится его «родительский».

Я понимаю, что это не совсем то решение, которое вы запрашивали, но именно так я бы решил эту проблему:)

...