Как запустить дочерний процесс и родительский процесс одновременно - PullRequest
1 голос
/ 26 апреля 2011

У меня есть веб-страница, которая отправляет запрос скрипту cgi, который в основном должен архивировать и сжимать огромные каталоги, которые могут быть более 50G.Я разветвляю процесс в моем скрипте cgi, который выполняет задачу tarring, пока я отправляю сообщение msg на веб-страницу в моем родительском скрипте.Однако родительский скрипт (даже при отсутствии waitpid ($ pid, 0) ожидает завершения процесса tar и затем отправляет сообщение на веб-страницу, которая затем выводится через окно с предупреждением. Есть ли способ, которым я могуотправьте msg сразу, чтобы пользователь знал, что процесс tarring был запущен, и этот процесс может продолжаться в фоновом режиме. Я не хочу делать exec (), так как мне нужно перехватывать любые ошибки при создании этого tarball.

Кроме того, будут ли какие-либо проблемы с памятью, когда я попытаюсь скопировать такие большие каталоги?

$SIG{CHLD} = 'IGNORE';
$|++;
$pid = fork();
if($pid){ sendResponse($data); exit; }
elsif($pid == 0)
{
    setsid();
    $gpid = fork();
    if(! $gpid)
    {
        qx(tar up big directories over 50G...);
    }
}

1 Ответ

2 голосов
/ 26 апреля 2011

Ваш первоначальный "статусный" ответ клиенту, вероятно, где-то буферизован. Если исполнитель CGI спроектирован правильно, небуферизованный поток вывода или запрос на очистку потока должны привести к тому, что все пакеты будут отправлены клиенту (где они могут быть буферизованы при получении, но это вне вашего контроля).

См. FAQ по Perl Как очистить / снять буфер дескриптора выходного файла? Почему я должен это делать? , чтобы не буферизовать ваш первоначальный ответ.

Обратите внимание, что среда CGI также, вероятно, вызывает waitpid () или аналогичный, поэтому вы не видите результатов до тех пор, пока существует дочерний процесс. Если вы хотите, чтобы дочерний процесс сохранялся после того, как запрос или клиент исчезли, вам необходимо отсоединить дочерний процесс от родительского. См. Полная Разобщенность Ребенка с Родителем в perlipc.

Поскольку вы будете иметь дело с очень большими объемами данных (50 ГБ), это займет довольно много времени. Весьма вероятно, что клиент или сервер могут ожидать некоторого тайм-аута в ожидании завершения tar. Чтобы избежать этого, вы можете гарантировать, что и клиент, и сервер имеют безумно долгий тайм-аут или периодически отправлять данные между ними, чтобы поддерживать соединение / запрос живым. Возможно, вы захотите отключить процесс tar и заставить клиента периодически опрашивать сервер для получения результата.

Наконец, если предположить, что tar не записывает данные в буфер в памяти, он должен быть относительно эффективным для использования памяти (при условии современного оборудования). Тем не менее, он может потреблять много ресурсов процессора и ввода-вывода. Я определенно буду осторожен с безопасностью службы и возможностью (непреднамеренного) отказа в обслуживании.

...