Каков наилучший способ параллельного выполнения задач в Ksh и Perl?

StackOverflow https://stackoverflow.com/questions/248332

Вопрос

У меня есть большой проект 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 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; ), чтобы зависимый элемент не запустился до тех пор, пока не завершится его «родительский».

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

scroll top