fork () создает ошибку во время выполнения, правильно ли я ее использую? - PullRequest
1 голос
/ 03 февраля 2012

У меня есть написанная на Perl программа, которая анализирует SQL-подобные операторы и создает задание для запуска на мэйнфрейме, которое извлекает поля и записи на основе критериев. Записи возвращаются на ПК и затем выводятся в различных форматах (например, CSV, XML и т. Д.). Я выбрал SQL-предложение INTO для вывода списка файлов и выводов.

Проблема в том, что запись записей в базу данных SQLite (один из форматов вывода) занимает относительно много времени, и я не хочу, чтобы это задерживало обработку следующей команды SQL (в случае, если имеется несколько запросов SQL прошло в). Поэтому я решил использовать fork (), чтобы это произошло.

Оригинальный бит кода:

foreach (@into) {
    dointo($_,$recs);
}

@ into - это список файлов и форматов (например, «File1.csv» - это формат с разделителями-запятыми, отправляемый в File1.csv, «File1.xml» - это формат XML, записанный в File1.xml и т. Д.) Для быть обработанным. Подпрограмма dointo обрабатывает каждый из них. $ recs - это своего рода итератор, который возвращает записи в различных форматах (flat, anonhash, anonarray и т. д.)

Итак, я изменил код на:

foreach (@into) {
    unless (fork()) {
        dointo($_,$recs);
        exit 0;
    }
}

но теперь, когда код выполняется, он, кажется, работает, но каждый раз выдает ошибку времени выполнения.

Я не перехватил возврат из fork (), потому что мне действительно не важно ждать окончания разветвленного процесса. Может ли это быть ошибкой? Нужно ли родительскому процессу дождаться завершения дочерних процессов, прежде чем он сможет безопасно завершить работу?

Буду признателен за любую помощь.

(Кстати, Windows XP - это ОС, Activestate Perl 5.10.0 - это версия Perl)

Ответы [ 2 ]

4 голосов
/ 03 февраля 2012
0 голосов
/ 03 февраля 2012

Форк на Windows всегда был немного хитрым.Помните, что fork () может возвращать два ложных значения: 0, если вы находитесь в дочернем процессе, и undef, если не удалось выполнить разветвление.Так что для вашего кода выше, у вас может быть неудачный форк.Кроме того, если вы не хотите ждать своих детей, я думаю, вам следует установить для $ SIG {CHLD} значение «IGNORE», чтобы избежать создания зомби, если вы не ждете.

См. Perlipc, perlfaq8 иwaitpid для получения дополнительной информации.Кроме того, было бы полезно, если бы вы сказали, что это за ошибка во время выполнения:)

Я забыл упомянуть, что вы также можете посмотреть на Parallel :: ForkManager .Это сделает это проще для вас.

И посмотрите perlfork , чтобы понять ограничения эмуляции форка в Windows.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...