Хобрук: Ваш путь к мастерству в программировании

Форк в Perl не работает внутри цикла чтения из файла

Я запускаю цикл while, читая каждую строку в файле, а затем разветвляю процессы с данными строки дочернему элементу. После N строк я хочу дождаться завершения дочерних процессов и продолжить следующие N строк и т.д.

Это выглядит примерно так:

    while ($w=<INP>) {

        # ignore file header
        if ($w=~m/^\D/) { next;}

        # get data from line
        chomp $w;
        @ws = split(/\s/,$w);

        $m = int($ws[0]);
        $d = int($ws[1]);
        $h = int($ws[2]);

        # only for some days in the year
        if (($m==3)and($d==15) or ($m==4)and($d==21) or ($m==7)and($d==18)) {

                die "could not fork" unless defined (my $pid = fork);

                unless ($pid) {

                        some instructions here using $m, $d, $h ...

                }
                push @qpid,$pid;

                # when all processors are busy, wait for child processes
                if ($#qpid==($procs-1)) {
                        for my $pid (@qpid) {
                                waitpid $pid, 0;
                        }
                        reset 'q';
                }
        }
}

close INP;

Это не работает. После первого раунда процессов я получаю какой-то PID, равный 0, массив @qpid перемешивается, и файл начинает читаться в (видимо) случайных местах, прыгая туда-сюда. Конечным результатом является то, что большинство строк в файле читаются два или три раза. Любые идеи?

Заранее большое спасибо,

S.

09.04.2010

  • Пожалуйста, use strict и use warnings. Эти прагмы имеют большое значение для уменьшения боли, связанной с отладкой. Хотя они не помогли бы с этой проблемой, в целом они имеют огромное значение. 09.04.2010

Ответы:


1

Вы выходите внутри unless ($pid)?

Если нет, то ваш ребенок после запуска команды добавит $pid нуля в массив и вообще продолжит выполнение того, что должно быть кодом родительского процесса.

09.04.2010

2

Я обеспокоен тем, что ваш алгоритм не очень эффективен:

Пусть базовый процесс разветвляет процессы от 1 до N.

Если процессы со 2 по N завершатся раньше, чем процесс 1, то новые процессы не будут запущены, пока не завершится процесс 1.

Вместо того, чтобы пытаться получить правильные детали вашей реализации, используйте Parallel::ForkManager легко получить рабочий код.

use strict;
use warnings;
use Parallel::ForkManager;

my $pm = Parallel::ForkManager->new($MAX_PROCESSES);

while( my $w=<INP> ) {

    next if $w=~m/^\D/;        # ignore file header

    chomp $w;

    next unless match_dates( $w,
        { m => 3, d => 15 }, 
        { m => 7, d => 18 },
        { y => 2008       },  # Added this to show match_dates() capability.
    );

    my $pid = $pm->start and next; 

        .. Do stuff in child here ..

    $pm->finish;  # Terminate child
}

close INP;

# Returns true if ANY of the supplied date templates matches for ALL keys defined in that template.
sub match_dates {
    my $string = shift;

    my %target;
    @target{qw( m d y )} = split(/\s/,$string);

    DATE:
    for my $date ( @_ ) {

        my @k = keys %$match;
        my $count = 0;

        for( @k ) {
            next DATE unless $date{$_} == $target{$_};
            $count++;
        }

        return 1 if $count == @k;  # All keys match

    }

    return;
} 
09.04.2010
Новые материалы

Решения DBA Metrix
DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

Начало работы с Блум
Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...