2013-10-14 212 views
1

我努力學習fork這是一個簡單的程序:退出子進程,安全

#!/usr/bin/perl 
# PRGNAME.pl by Whom 
# 
# 
use strict; 
use warnings; 

main(@ARGV); 

sub main 
{ 
    my @array = qw(1 2 3 4 5 6); 
    while ((my $t = pop @array)) { 
     if (! (my $pid = fork)) { 
       exit if ($t == 2); 
       for(;;){} 
     } 
    } 
    waitpid(-1, 0); 
    message("This is the $PRGNAME exercise file."); 
} 

sub message 
{ 
    my $m = shift or return; 
    print("$m\n"); 
} 

sub error 
{ 
    my $e = shift || 'unkown error'; 
    print("$0: $e\n"); 
    exit 0; 
} 

但是在外殼上時,我想:ps -fu $LOGNAME | grep [f]ork,我發現:

i59tib 28361  1 3 16:20:07 pts/34  6:07 /usr/bin/perl ./fork.pl 
    i59tib 28363  1 3 16:20:07 pts/34  6:07 /usr/bin/perl ./fork.pl 
    i59tib 28366  1 3 16:20:07 pts/34  6:07 /usr/bin/perl ./fork.pl 
    i59tib 28364  1 3 16:20:07 pts/34  6:07 /usr/bin/perl ./fork.pl 
    i59tib 28362  1 3 16:20:07 pts/34  6:08 /usr/bin/perl ./fork.pl 

在這裏,人們當我評論此行exit if ($t == 2);

並再次運行ps -fu $LOGNAME | grep [f]ork我發現:

i59tib 624 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 629 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 628 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 625 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 627 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 626 623 1 16:29:11 pts/34  0:04 /usr/bin/perl ./fork.pl 
    i59tib 623 4766 0 16:29:11 pts/34  0:00 /usr/bin/perl ./fork.pl 

如何退出子進程而不退出父進程?

回答

3

如何退出子進程而不退出父進程?

由於父母到達程序結束,所以父母退出,所以告訴父母要做些什麼,什麼!例如,

1 while waitpid(-1, 0) > 0; 
+0

不,由於'waitpid(-1,0);父母等待所有進程;'我知道這一點,因爲我測試了它。如果您對'exit'進行了評論,那麼父母不會退出,直到孩子完成。 –

+0

請仔細看看第二個'ps' –

+0

如果你不相信我,那麼你發佈的測試證明是相反的,而[documentation](http://linux.die.net/man/2/waitpid),那麼你爲什麼打擾問? – ikegami

0

我怎樣才能退出而不退出父,子進程?

請在此處嘗試下面的程序孩子在父母面前死去。

#!/usr/bin/perl 
print "i am about to fork\n"; 
my $pid = fork(); 
if($pid > 0) { 
    my $i = 0; 
    while($i<5) { 
     print "PARENT--I will be keep on running\n"; 
     sleep(5); 
     $i++; 
    } 
    print "PARENT-- I m about to dead\n"; 
} else { 
    $i = 0; 
    while($i <3) { 
     print "CHILD-- I will be dead before than parent\n"; 
     #exit(0); you can put exit like this also. 
     sleep(2); 
     $i++; 
    } 
    print "CHILD-- I m about to dead\n"; 
} 

下面是示例輸出。

i am about to fork 
PARENT--I will be keep on running 
CHILD-- I will be dead before than parent 
CHILD-- I will be dead before than parent 
CHILD-- I will be dead before than parent 
PARENT--I will be keep on running 
CHILD-- I m about to dead 
PARENT--I will be keep on running 
PARENT--I will be keep on running 
PARENT--I will be keep on running 
PARENT-- I m about to dead 

你可以使用任何支持的信號存在also.You可以得到不同的信號列表here。您也可以在循環中使用相同的示例代碼,但請確保這裏有一個超級父代,其他代表將是他們的子代。

請運行該程序瞭解更多關於此。無論您使用退出還是不退出,超級父母總是會退出。

#!/usr/bin/perl 
print "i $$ am about to fork\n"; 
my @children_pids; 
my $n = 3; 
for my $i (0..($n-1)) { 
    my $pid = fork(); 
    if($pid > 0) { 
     print "i m $$ child of".getppid()."\n"; 
     push @children_pids, $pid; 
    } else { 
     print "I $$ is about to dead. I am child of".getppid()."\n"; 
     exit(); 
    } 
} 
waitpid $_, 0 for @children_pids; 
print "$$ is finished\n"; 

以上程序的系統典型輸出如下。

i 3919 am about to fork 
i m 3919 child of3092 
I 3920 is about to dead. I am child of3919 
i m 3919 child of3092 
i m 3919 child of3092 
I 3921 is about to dead. I am child of3919 
I 3922 is about to dead. I am child of3919 
3919 is finished 

父母將等待其所有孩子退出;然後只有退出。

+0

你的程序在這裏使用正常的退出,它不會產生任何異常行爲,但是如果你明確地發出'exit'子例程呢? –

+0

您也可以使用退出也。我已評論它。請檢查下一個程序瞭解更多關於此。 – virus