To jest polecenie perlfork, które można uruchomić u dostawcy bezpłatnego hostingu OnWorks przy użyciu jednej z naszych wielu bezpłatnych stacji roboczych online, takich jak Ubuntu Online, Fedora Online, emulator online systemu Windows lub emulator online systemu MAC OS
PROGRAM:
IMIĘ
perlfork – emulacja fork() w Perlu
STRESZCZENIE
UWAGA: Od wersji 5.8.0 emulacja fork() znacznie się poprawiła
dojrzał. Jednak nadal istnieje kilka znanych błędów i różnic
z prawdziwego fork(), który może na Ciebie wpłynąć. Zobacz „BŁĘDY” i
Poniżej znajdują się sekcje „OSTRZEŻENIA I OGRANICZENIA”.
Perl zapewnia widelec() słowo kluczowe odpowiadające wywołaniu systemowemu Uniksa o tej samej nazwie.
Na większości platform typu Unix, gdzie widelec() dostępne jest wywołanie systemowe, Perla widelec()
po prostu to nazywa.
Na niektórych platformach, takich jak Windows, gdzie plik widelec() wywołanie systemowe nie jest dostępne, Perl może to zrobić
być zbudowany do naśladowania widelec() na poziomie tłumacza. Chociaż emulacja jest przeznaczona
być jak najbardziej zgodne z rzeczywistością widelec() tam na poziomie programu Perl
są pewne istotne różnice, które wynikają z faktu, że wszystkie pseudodziecka
„procesy” utworzone w ten sposób żyją w tym samym rzeczywistym procesie, aż do systemu operacyjnego
jest zaniepokojony.
Dokument ten zawiera ogólny przegląd możliwości i ograniczeń programu
widelec() współzawodnictwo. Należy pamiętać, że omówione tutaj kwestie nie dotyczą platform
gdzie prawdziwy widelec() jest dostępny i Perl został skonfigurowany do jego używania.
OPIS
widelec() emulacja jest realizowana na poziomie interpretera Perla. Co to znaczy
ogólnie to jest bieganie widelec() faktycznie sklonuje działający interpreter i wszystkie jego
state i uruchom sklonowany interpreter w osobnym wątku, rozpoczynając wykonywanie w nowym
wątek zaraz za punktem, w którym znajduje się plik widelec() został wezwany do rodzica. Będziemy się odnosić
wątek, który implementuje ten „proces” potomny jako pseudoproces.
Do programu Perl, który wywołał widelec(), wszystko to ma być przejrzyste. The
rodzic wraca z widelec() z identyfikatorem pseudoprocesu, który można później wykorzystać
dowolne funkcje manipulacji procesami; dziecko wraca z widelec() o wartości od 0 do
oznacza, że jest to pseudoproces potomny.
Zachowanie of Inne Perl cechy in rozwidlony pseudoprocesy
Większość funkcji Perla zachowuje się w naturalny sposób w ramach pseudoprocesów.
$$ lub $PROCESS_ID
Ta specjalna zmienna jest poprawnie ustawiona na identyfikator pseudoprocesu. To może być użyte
do identyfikacji pseudoprocesów w ramach określonej sesji. Należy pamiętać, że jest to wartość
podlegać recyklingowi, jeśli jakiekolwiek pseudoprocesy zostaną uruchomione po innych
czekać()-ed dalej.
%ENV Każdy pseudoproces utrzymuje swoje własne środowisko wirtualne. Modyfikacje %ENV
wpływają na środowisko wirtualne i są widoczne jedynie w obrębie tego pseudoprocesu,
oraz we wszelkich procesach (lub pseudoprocesach) z niego uruchamianych.
chdir() i wszystkie inne wbudowane funkcje, które akceptują nazwy plików
Każdy pseudoproces utrzymuje swoją własną wirtualną koncepcję bieżącego katalogu.
Modyfikacje w bieżącym katalogu za pomocą chdir() są widoczne tylko w tym
pseudoprocesie oraz we wszelkich procesach (lub pseudoprocesach) z niego uruchamianych. Wszystko
dostęp do plików i katalogów z pseudoprocesu będzie poprawnie mapował wirtualność
katalog roboczy do prawdziwego katalogu roboczego.
czekać() oraz pid()
czekać() oraz pid() można przekazać identyfikator pseudoprocesu zwrócony przez widelec(), Te
wywołania będą prawidłowo czekać na zakończenie pseudoprocesu i go zwrócą
stan.
zabić() „kill('KILL', ...)” może zostać użyte do zakończenia pseudoprocesu poprzez przekazanie mu identyfikatora
zwrócone przez widelec(). Wynik zabójstwa w pseudoprocesie jest nieprzewidywalny i
nie należy go używać, chyba że w sytuacjach krytycznych, ze względu na działanie
system może nie gwarantować integralności zasobów procesu, gdy wątek jest uruchomiony
zostaje zakończony. Proces realizujący pseudoprocesy można zablokować
i interpreter Perla zawiesza się. Zauważ, że użycie „kill('KILL', ...)” na pliku
rzekomy-proces() może zazwyczaj powodować wycieki pamięci, ponieważ wątek that
implementuje pseudoproces, nie ma szans na oczyszczenie swoich zasobów.
„kill('TERM', ...)” może być również użyte w pseudoprocesach, ale sygnał nie będzie
zostać dostarczony, gdy pseudoproces jest blokowany przez wywołanie systemowe, np. oczekiwanie
aby gniazdo mogło się połączyć, lub próbuje odczytać dane z gniazda, w którym nie ma dostępnych danych.
Począwszy od Perla 5.14, proces nadrzędny nie będzie czekał na jednokrotne zakończenie procesu potomnego
zostały one zasygnalizowane za pomocą „kill('TERM', ...)”, aby uniknąć zakleszczenia podczas procesu
Wyjście. Będziesz musiał wyraźnie zadzwonić pid() żeby mieć pewność, że dziecko ma czas
posprzątać, ale wtedy jesteś także odpowiedzialny za to, że dziecko tego nie robi
blokowanie wejść/wyjść również.
Exec () powołanie Exec () w pseudoprocesie faktycznie tworzy żądany plik wykonywalny
oddzielny proces i czeka na jego zakończenie, zanim zakończy się tym samym wyjściem
status jako ten proces. Oznacza to, że identyfikator procesu zgłoszony w pliku
uruchomienie pliku wykonywalnego będzie się różnić od tego, co działało we wcześniejszym Perlu widelec() może mieć
zwrócony. Podobnie wszelkie funkcje manipulacji procesami stosowane do identyfikatora
zwrócone przez widelec() wpłynie to na oczekujący pseudoproces, który wywołał Exec (), Nie
prawdziwy proces, na który czeka po Exec ().
Kiedy Exec () jest wywoływany wewnątrz pseudoprocesu, a następnie DESTROY metody i bloki END
będzie nadal wywoływany po powrocie procesu zewnętrznego.
wyjście() wyjście() zawsze kończy właśnie wykonujący się pseudoproces, po czym następuje automatycznie
czekać()-ing dla wszelkich zaległych pseudoprocesów potomnych. Zauważ, że to oznacza to
proces jako całość nie zakończy się, chyba że wszystkie działające pseudoprocesy to zrobią
wyszedł. Poniżej znajdziesz niektóre ograniczenia dotyczące otwartych uchwytów plików.
Otwórz uchwyty do plików, katalogów i gniazd sieciowych
Wszystkie otwarte uchwyty są dup()-ed w pseudoprocesach, tak że zamknięcie wszelkich uchwytów
jeden proces nie wpływa na pozostałe. Poniżej znajdziesz informacje o niektórych ograniczeniach.
Zasób Limity
W oczach systemu operacyjnego pseudoprocesy tworzone za pośrednictwem widelec() emulacje są
po prostu wątki w tym samym procesie. Oznacza to, że wszelkie ograniczenia na poziomie procesu nałożone przez
system operacyjny ma zastosowanie do wszystkich pseudoprocesów razem wziętych. Obejmuje to dowolne
ograniczenia nałożone przez system operacyjny na liczbę otwartych plików, katalogów i gniazd
uchwyty, ograniczenia wykorzystania miejsca na dysku, ograniczenia rozmiaru pamięci, ograniczenia wykorzystania procesora itp.
Zabicie dotychczasowy roślina mateczna wygląda tak
Jeśli proces nadrzędny zostanie zabity (albo przy użyciu Perla zabić() wbudowany lub używający niektórych
środki zewnętrzne) wszystkie pseudoprocesy również są zabijane i cały proces kończy się.
Życie of dotychczasowy roślina mateczna wygląda tak oraz pseudoprocesy
Podczas normalnego przebiegu zdarzeń proces nadrzędny i każdy pseudoproces rozpoczęty przez
będzie czekać, aż ich pseudo-dzieci zakończą pracę, zanim wyjdą. Ten
oznacza, że rodzic i każde utworzone przez niego pseudodziecko jest także pseudorodzicem
wyjdą dopiero po wyjściu ich pseudodzieci.
Począwszy od Perla 5.14, rodzic nie będzie tego robił czekać() automatycznie dla każdego dziecka, które było
sygnalizowane za pomocą „kill('TERM', ...)”, aby uniknąć impasu w przypadku, gdy dziecko blokuje
I/O i nigdy nie odbiera sygnału.
OSTRZEŻENIA ROLNICZE OGRANICZENIA
ZACZNIJ bloki
widelec() emulacja nie będzie działać całkowicie poprawnie, gdy zostanie wywołana z poziomu a
ROZPOCZNIJ blok. Rozwidlona kopia uruchomi zawartość bloku BEGIN, ale tak się stanie
nie kontynuuj analizowania strumienia źródłowego po bloku BEGIN. Na przykład,
rozważ następujący kod:
ZACZYNAĆ {
rozwidlenie i wyjście; # rozwidl dziecko i wyjdź z rodzica
drukuj „wewnętrzny\n”;
}
wydrukuj „zewnętrzny\n”;
Spowoduje to wydrukowanie:
wewnętrzny
zamiast oczekiwanego:
wewnętrzny
zewnętrzny
Ograniczenie to wynika z podstawowych trudności technicznych związanych z klonowaniem i
ponowne uruchomienie stosów używanych przez parser Perla w środku analizy.
Otwórz uchwyty plików
Wszelkie uchwyty plików otwarte w momencie widelec() będzie dup()-wyd. Tym samym pliki
można zamknąć niezależnie w elemencie nadrzędnym i podrzędnym, ale należy pamiętać, że dup()-red
uchwyty nadal będą miały ten sam wskaźnik wyszukiwania. Zmiana pozycji wyszukiwania w pliku
rodzic zmieni to w dziecku i odwrotnie. Można tego uniknąć otwierając
pliki, które wymagają odrębnych wskaźników wyszukiwania oddzielnie w pliku podrzędnym.
W niektórych systemach operacyjnych, zwłaszcza Solaris i Unixware, wywołanie „exit()” z pliku a
W ten sposób proces potomny opróżni i zamknie otwarte uchwyty plików u rodzica
uszkodzenie uchwytów plików. W tych systemach sugerowane jest wywołanie „_exit()”.
Zamiast. Funkcja „_exit()” jest dostępna w Perlu poprzez moduł „POSIX”. Proszę
więcej informacji na ten temat znajdziesz na stronach podręcznika systemu.
Otwórz uchwyty katalogów
Perl będzie całkowicie czytać ze wszystkich otwartych uchwytów katalogów, aż dotrą do końca
strumienia. To będzie wtedy szukajkatalogu() z powrotem do pierwotnej lokalizacji i wszystko
przyszłość katalog_odczytu() żądania będą realizowane z bufora pamięci podręcznej. To znaczy
że ani uchwyt katalogu przechowywany przez proces nadrzędny, ani ten utrzymywany przez proces nadrzędny
proces potomny zobaczy wszelkie zmiany wprowadzone w katalogu po widelec()
połączenie.
Należy pamiętać, że katalog wsteczny() ma podobne ograniczenie w systemie Windows i nie będzie wymuszane
katalog_odczytu() aby ponownie przeczytać katalog. Tylko nowo otwarty katalog
handle będzie odzwierciedlać zmiany w katalogu.
Rozwidlona rura otwarty() jeszcze nie zaimplementowane
Konstrukcje „open(FOO, „|-”)” i „open(BAR, „-|”)” nie zostały jeszcze zaimplementowane.
To ograniczenie można łatwo obejść w nowym kodzie, tworząc potok
wyraźnie. Poniższy przykład pokazuje, jak pisać do rozwidlonego dziecka:
# symuluj otwarcie (FOO, "|-")
sub pipe_to_fork ($) {
mój $rodzic = zmiana;
puść moje $dziecko, $rodzic lub umrzyj;
mój $pid = widelec();
die „fork() nie powiódł się: $!” chyba że zdefiniowano $pid;
jeśli ($pid) {
zamknij $dziecko;
}
else {
zamknij $rodzic;
open(STDIN, "<&=" .fileno($child)) lub die;
}
$pid;
}
if (pipe_to_fork('FOO')) {
# rodzic
wydrukuj FOO „pipe_to_fork\n”;
zamknij inspektora obsługi;
}
else {
# dziecko
dopóki ( ) { drukuj; }
wyjście(0);
}
A ten czyta od dziecka:
# symuluj otwarcie (FOO, "-|")
sub pipe_from_fork ($) {
mój $rodzic = zmiana;
pisz $rodzic, moje $dziecko albo umrzyj;
mój $pid = widelec();
die „fork() nie powiódł się: $!” chyba że zdefiniowano $pid;
jeśli ($pid) {
zamknij $dziecko;
}
else {
zamknij $rodzic;
open(STDOUT, ">&=" .fileno($child)) lub die;
}
$pid;
}
if (pipe_from_fork('BAR')) {
# rodzic
chwila ( ) { drukuj; }
zamknij BAR;
}
else {
# dziecko
wydrukuj „pipe_from_fork\n”;
wyjście(0);
}
Rozwidlona rura otwarty() konstrukcje będą obsługiwane w przyszłości.
Stan globalny utrzymywany przez XSUB
Podprogramy zewnętrzne (XSUB), które utrzymują swój własny stan globalny, mogą nie działać
prawidłowo. Takie jednostki XSUB będą musiały utrzymywać blokady w celu jednoczesnej ochrony
dostęp do globalnych danych z różnych pseudoprocesów lub utrzymanie ich całego stanu
w tabeli symboli Perla, która jest kopiowana w sposób naturalny, gdy widelec() jest nazywany. A
mechanizm wywołania zwrotnego, który zapewnia rozszerzeniom możliwość klonowania swojego stanu
zostaną podane w najbliższej przyszłości.
Tłumacz wbudowany w większą aplikację
widelec() emulacja może nie zachowywać się zgodnie z oczekiwaniami, gdy jest wykonywana w pliku
aplikacja, która osadza interpreter Perla i wywołuje API Perla, które mogą oceniać
bity kodu Perla. Wynika to z faktu, że emulacja posiada jedynie wiedzę
o własnych strukturach danych interpretera Perla i nie wie nic o
zawierający stan aplikacji. Na przykład każdy stan prowadzony na
własny stos wywołań aplikacji jest poza zasięgiem.
Bezpieczeństwo gwintów przedłużeń
Ponieważ widelec() emulacja uruchamia kod w wielu wątkach, wywołując rozszerzenia
Biblioteki, które nie są bezpieczne dla wątków, mogą nie działać niezawodnie podczas wywoływania widelec(). Jak Perla
obsługa wątków stopniowo staje się coraz szerzej stosowana nawet na platformach z
rodzimy widelec(), oczekuje się, że takie rozszerzenia zostaną naprawione ze względu na bezpieczeństwo wątków.
RUCHLIWOŚĆ OSTRZEŻENIA
W przenośnym kodzie Perla „kill(9, $child)” nie może być używane w rozwidlonych procesach. Zabicie A
rozwidlony proces jest niebezpieczny i ma nieprzewidywalne skutki. Widzieć "zabić()", powyżej.
Korzystaj z perlfork online, korzystając z usług onworks.net
