2013-10-14 135 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