I'm baffled that pid's are zero within a block, but not so when they finish.

fork causes the execution of a process to split into two different processes, sharing the initial memory layout but not the following changes to the variables. To help the program discern which of the two it has become, the newly produced ("child") process receives 0 as the return value of fork() and the old one ("parent") gets returned the PID of the new process. This is why you had to put an exit 0; at the end of the if ($pid == 0) block: otherwise both the parent and the child would continue executing the same parts of the program, causing a lot of confusion.

wait returns the real (former) PIDs of the freshly terminated child processes. If the child wanted for some reason to know its PID, it could have used the $$ variable.

This example might help:

if (fork() == 0) { system("sh", "-c", "sleep 3 # getting yandex translation"); exit(0); } if (fork() == 0) { system("sh", "-c", "sleep 2; # getting google translation"); exit(0); } system("pstree -Apal $$"); # pstree gets the PID of the parent process + as its argument while((my $pid = wait()) != -1) { say "$pid terminated" } __END__ perl,29173 test.pl |-perl,29174 test.pl | `-sh,29177 -c sleep 3 # getting yandex translation | `-sleep,29179 3 |-perl,29175 test.pl | `-sh,29178 -c sleep 2; # getting google translation `-pstree,29176 -Apal 29173 29175 terminated 29174 terminated
pstree command draws all child processes of the main Perl process (including itself) with their command line arguments. The Perl processes having the same command line arguments but different PIDs are the copies created by fork().
What alarm truly does here is unclear. Finally, there is no code to kill pid's when the timer reaches zero.
alarm arranges for a SIGALRM signal to be delivered to the calling process in the number of seconds specified as its argument. It behaves as if something else kills the process which had called alarm and forgot to disarm it. The good part is that one can use $SIG{ALRM} to trap the signal and do something meaningful instead of dying, but in your case the work is already being done in a child process, and we can let it be killed:
my $start = time; if (fork() == 0) { # arm the alarm clock alarm(10); # create a child process that sleeps system("sleep 365d"); exit(0); } system("pstree -Apal $$"); while((my $pid = wait()) != -1) { say "$pid terminated" } say time-$start, " seconds elapsed instead of a year" __END__ perl,29620 |-perl,29621 | `-sleep,29623 365d `-pstree,29622 -Apal 29620 29621 terminated 10 seconds elapsed instead of a year

In reply to Re^3: using online translation engines with perl by Anonymous Monk
in thread using online translation engines with perl by Aldebaran

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.