perlfork - Інтернет у хмарі

Це команда perlfork, яку можна запустити в безкоштовному хостинг-провайдері OnWorks за допомогою однієї з наших безкоштовних онлайн-робочих станцій, таких як Ubuntu Online, Fedora Online, онлайн-емулятор Windows або онлайн-емулятор MAC OS

ПРОГРАМА:

ІМ'Я


perlfork - емуляція Perl fork().

СИНТАКСИС


ПРИМІТКА. Починаючи з випуску 5.8.0, емуляція fork() значно змінилася
дозрів. Однак є ще кілька відомих помилок і відмінностей
від реального fork(), що може вплинути на вас. Див. «ПОМИЛКИ» і
Розділи «ЗАСТЕРЕЖЕННЯ ТА ОБМЕЖЕННЯ» нижче.

Perl надає a вилка () ключове слово, яке відповідає однойменному системному виклику Unix.
На більшості Unix-подібних платформ, де вилка () системний виклик доступний, Perl вилка ()
просто називає це.

На деяких платформах, наприклад Windows, де вилка () системний виклик недоступний, Perl може
бути створеним для наслідування вилка () на рівні перекладача. У той час як емуляція призначена для
бути максимально сумісним з реальним вилка () на рівні програми Perl, там
є певні важливі відмінності, які випливають з того факту, що всі псевдодитини
"процеси", створені таким чином, живуть у тому самому реальному процесі, що й операційна система
Занепокоєний.

Цей документ містить загальний огляд можливостей і обмежень
вилка () емуляція. Зауважте, що обговорювані тут питання не стосуються платформ
де справжній вилка () доступний і Perl налаштовано для його використання.

ОПИС


Команда вилка () емуляція реалізована на рівні інтерпретатора Perl. Що це означає
загалом це те, що бігає вилка () фактично клонує запущений інтерпретатор і все його
і запустіть клонований інтерпретатор в окремому потоці, починаючи виконання в новому
нитка відразу після точки, де вилка () був названий в батьків. Ми будемо посилатися на
потік, який реалізує цей дочірній «процес» як псевдопроцес.

До програми Perl, яка викликала вилка (), все це створено для прозорості. The
батько повертається з вилка () з ідентифікатором псевдопроцесу, який згодом можна використовувати в
будь-які технологічні функції; дитина повертається з вилка () зі значенням від 0 до
означають, що це дочірній псевдопроцес.

Поведінка of інший Perl риси in вилка псевдопроцеси
Більшість функцій Perl поводяться природним чином у псевдопроцесах.

$$ або $PROCESS_ID
Цю спеціальну змінну правильно встановлено на ідентифікатор псевдопроцесу. Його можна використовувати
для ідентифікації псевдопроцесів у певній сесії. Зверніть увагу, що це значення
підлягає переробці, якщо будь-які псевдопроцеси запускаються після інших
почекати ()-ed on.

%ENV Кожен псевдопроцес підтримує власне віртуальне середовище. Зміни в %ENV
впливають на віртуальне середовище та є видимими лише в цьому псевдопроцесі,
і в будь-яких процесах (або псевдопроцесах), запущених з нього.

chdir() та всі інші вбудовані модулі, які приймають імена файлів
Кожен псевдопроцес підтримує власну віртуальну ідею поточного каталогу.
Зміни поточного каталогу за допомогою chdir() видно лише всередині цього
псевдопроцесі та в будь-яких процесах (або псевдопроцесах), запущених з нього. всі
доступ до файлів і каталогів із псевдопроцесу правильно відобразить віртуальний
робочий каталог у справжній робочий каталог відповідним чином.

почекати () та waitpid()
почекати () та waitpid() можна передати ідентифікатор псевдопроцесу, який повертає вилка (). Ці
виклики належним чином чекатимуть завершення псевдопроцесу та повертатимуть його
Статус.

вбити () "kill('KILL', ...)" можна використовувати для завершення псевдопроцесу, передавши йому ідентифікатор
повернуто до вилка (). Результат убивства псевдопроцесу є непередбачуваним і
його не слід використовувати, за винятком важких обставин, оскільки операційна
система може не гарантувати цілісність ресурсів процесу під час запущеного потоку
припиняється. Процес, який реалізує псевдопроцеси, може бути заблокований
і інтерпретатор Perl зависає. Зауважте, що використання "kill('KILL', ...)" на a
псевдо-процес() зазвичай може викликати витік пам'яті, оскільки потік, який
реалізує псевдопроцес, не отримує шансу очистити свої ресурси.

"kill('TERM', ...)" також можна використовувати для псевдопроцесів, але сигнал не буде
бути доставлено, поки псевдопроцес заблоковано системним викликом, наприклад. очікування
для підключення до сокета або спроба читання з сокета без доступних даних.
Починаючи з Perl 5.14, батьківський процес не чекатиме, поки дочірні процеси завершаться один раз
їм було повідомлено "kill('TERM', ...)", щоб уникнути блокування під час процесу
вихід. Вам доведеться явно дзвонити waitpid() щоб дитина встигала
щоб прибрати себе, але тоді ви також несете відповідальність за те, щоб дитина не була
блокування вводу-виводу.

exec () покликання exec () у межах псевдопроцесу фактично породжує запитуваний виконуваний файл
окремий процес і чекає його завершення перед тим, як вийти з тим самим виходом
статус цього процесу. Це означає, що ідентифікатор процесу повідомляється в межах
запущений виконуваний файл буде відрізнятися від попереднього Perl вилка () може мати
повернувся. Подібним чином, будь-які функції маніпулювання процесом застосовуються до ідентифікатора
повернуто до вилка () вплине на виклик псевдопроцесу, що очікує exec (), Чи не
реальний процес, якого він чекає після exec ().

Коли exec () викликається всередині псевдопроцесу, потім методи DESTROY і блоки END
буде викликано після повернення зовнішнього процесу.

вихід () вихід () завжди виходить лише з псевдопроцесу, що виконується, після автоматично
почекати ()-ing для будь-яких видатних дочірніх псевдопроцесів. Зауважте, що це означає, що
процес загалом не завершить роботу, якщо не завершать роботу всі запущені псевдопроцеси
вийшов. Нижче наведено деякі обмеження щодо відкритих дескрипторів файлів.

Відкрити описи файлів, каталогів і мережевих сокетів
Всі ручки відкриті dup()-ed у псевдопроцесах, так що закриття будь-яких маркерів у
один процес не впливає на інші. Деякі обмеження див. нижче.

Ресурс рамки
В очах операційної системи псевдопроцеси, створені за допомогою вилка () емуляція є
просто потоки в тому самому процесі. Це означає, що будь-які обмеження на рівні процесу, накладені
операційна система застосовується до всіх псевдопроцесів разом узятих. Сюди входить будь-який
обмеження, накладені операційною системою на кількість відкритих файлів, каталогів і сокетів
ручки, обмеження на використання дискового простору, обмеження на розмір пам'яті, обмеження на використання ЦП тощо.

Вбивство батько процес
Якщо батьківський процес закрито (або за допомогою Perl вбити () вбудовані або за допомогою деяких
зовнішніми засобами) усі псевдопроцеси також вбиваються, і весь процес завершується.

Тривалість Життя of батько процес та псевдопроцеси
Під час звичайного перебігу подій батьківський процес і кожен псевдопроцес, запущений
він чекатиме, поки їхні відповідні псевдодіти завершаться, перш ніж вони вийдуть. Це
означає, що батько та кожна створена ним псевдонащадка, яка також є псевдобатьком
вийде лише після того, як вийдуть їхні псевдодіти.

Починаючи з Perl 5.14, батьківський не буде почекати () автоматично для будь-якої дитини, яка була
сигналізується за допомогою "kill('TERM', ...)", щоб уникнути взаємоблокування, якщо дитина блокує на
I/O і ніколи не отримує сигнал.

ПЕРЕКЛАДИ І ОБМЕЖЕННЯ


Блоки BEGIN
Команда вилка () емуляція працюватиме не зовсім коректно під час виклику з a
блок BEGIN. Розгалужена копія запускатиме вміст блоку BEGIN, але буде
не продовжувати розбирати вихідний потік після блоку BEGIN. Наприклад,
розглянути наступний код:

ПОЧАТИ {
розвилка і вихід; # розгалужувати дочірній елемент і виходити з батьківського
надрукувати "inner\n";
}
надрукувати "зовнішній\n";

Буде надруковано:

внутрішній

а не очікуване:

внутрішній
зовнішній

Це обмеження виникає через фундаментальні технічні труднощі клонування та
перезапуск стеків, які використовуються синтаксичним аналізатором Perl у середині аналізу.

Відкрити дескриптори файлів
Будь-які дескриптори файлів, відкриті під час вилка () буде dup()- ред. Таким чином, файли
може бути закрито незалежно в батьківському та дочірньому елементі, але пам’ятайте, що dup()-ед
маркери все одно матимуть той самий покажчик пошуку. Зміна позиції пошуку в
батько змінить його в дитині і навпаки. Цього можна уникнути, відкривши
файли, які потребують окремих покажчиків пошуку окремо в дочірньому.

У деяких операційних системах, зокрема Solaris і Unixware, виклик "exit()" з a
дочірній процес очищає та закриває відкриті дескриптори файлів у батьківському, таким чином
пошкодження дескрипторів файлів. У цих системах пропонується викликати "_exit()".
замість цього. "_exit()" доступний у Perl через модуль "POSIX". Будь ласка
зверніться до сторінок довідки вашої системи, щоб дізнатися більше про це.

Відкрити маркери каталогу
Perl повністю читатиме всі дескриптори відкритого каталогу, поки вони не досягнуть кінця
потоку. Тоді буде seekdir() повернутися до вихідного місця і все
майбутнє readdir() запити виконуватимуться з кеш-буфера. Це означає
що ні дескриптор каталогу, який зберігається батьківським процесом, ні той, що зберігається
дочірній процес побачить усі зміни, внесені до каталогу після вилка ()
дзвінок.

Зверніть увагу, що rewinddir() має подібне обмеження для Windows і не буде примусово
readdir() щоб знову прочитати каталог. Тільки нещодавно відкритий каталог
дескриптор відображатиме зміни в каталозі.

Розгалужена труба відчинено() ще не реалізовано
Конструкції "open(FOO, "|-)" та "open(BAR, "-|")" ще не реалізовано.
Це обмеження можна легко обійти в новому коді, створивши канал
явно. У наступному прикладі показано, як писати розгалуженому нащадку:

# імітувати відкриття (FOO, "|-")
sub pipe_to_fork ($) {
мій $parent = shift;
трубити мій $child, $parent або померти;
мій $pid = fork();
die "fork() не вдалося: $!" якщо не визначено $pid;
якщо ($pid) {
закрити $child;
}
ще {
закрити $parent;
open(STDIN, "<&=" . fileno($child)) або померти;
}
$pid;
}

if (pipe_to_fork('FOO')) {
#батько
print FOO "pipe_to_fork\n";
закрити FOO;
}
ще {
# дитина
while () { print; }
вихід(0);
}

А цей читає у дитини:

# моделювати відкриття (FOO, "-|")
sub pipe_from_fork ($) {
мій $parent = shift;
трубити $батька, мою $дитину або померти;
мій $pid = fork();
die "fork() не вдалося: $!" якщо не визначено $pid;
якщо ($pid) {
закрити $child;
}
ще {
закрити $parent;
open(STDOUT, ">&=" . fileno($child)) або померти;
}
$pid;
}

if (pipe_from_fork('BAR')) {
#батько
while () { print; }
закрити БАР;
}
ще {
# дитина
вивести "pipe_from_fork\n";
вихід(0);
}

Розгалужена труба відчинено() конструкції підтримуватимуться в майбутньому.

Глобальний стан, який підтримується XSUB
Зовнішні підпрограми (XSUB), які підтримують власний глобальний стан, можуть не працювати
правильно. Таким XSUB потрібно або підтримувати блокування для одночасного захисту
отримати доступ до глобальних даних з різних псевдопроцесів або підтримувати весь їхній стан
у таблиці символів Perl, яка природним чином копіюється, коли вилка () називається. А
механізм зворотного виклику, який надає розширенням можливість клонувати свій стан
буде надано найближчим часом.

Інтерпретатор, вбудований у велику програму
Команда вилка () емуляція може поводитися не так, як очікувалося, коли вона виконується в
програма, яка вбудовує інтерпретатор Perl і викликає Perl API, які можуть оцінювати
біти коду Perl. Це пов’язано з тим, що емуляція має лише знання
про власні структури даних інтерпретатора Perl і нічого не знає про
містить стан програми. Наприклад, будь-яка держава здійснювала свою
власний стек викликів програми недоступний.

Потокобезпечність розширень
З вилка () емуляція виконує код у кількох потоках, викликаючи розширення
небезпечні для потоків бібліотеки можуть не працювати надійно під час виклику вилка (). Як у Perl
підтримка потоків поступово набуває більшого поширення навіть на платформах з a
рідний вилка (), очікується, що такі розширення будуть виправлені для потокової безпеки.

ПОРТОБІЛЬНІСТЬ ПЕРЕКЛАДИ


У портативному коді Perl "kill(9, $child)" не можна використовувати для розгалужених процесів. Вбивство а
Роздвоєний процес є небезпечним і має непередбачувані результати. Побачити "вбити ()", вище.

Використовуйте perlfork онлайн за допомогою сервісів onworks.net



Найновіші онлайн-програми для Linux і Windows