linux – 为什么waitpid不等待进程退出?

前端之家收集整理的这篇文章主要介绍了linux – 为什么waitpid不等待进程退出?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在下面的脚本中,我试图弄清楚waitpid是如何工作的,但它不会等待ssh进程退出.完成后立即打印,而不是在ssh过程存在之后.

当我给它的pid退出时,如何才使waitpid继续?

  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Parallel::ForkManager;
  5. use POSIX ":sys_wait_h";
  6.  
  7. my $pm = Parallel::ForkManager->new(5);
  8. my $pid = $pm->start;
  9. my $p = $pid;
  10. if (!$pid) {
  11. system("ssh 10.10.47.47 sleep 10");
  12. $pm->finish;
  13. }
  14.  
  15. $p = qx(/usr/bin/pgrep -P $p);
  16. print "ssh pid is $p\n";
  17.  
  18. my $kid;
  19. do {
  20. $kid = waitpid($p,0);
  21. } while $kid > 0;
  22.  
  23. print "done\n";

我也试过了

  1. while (1) {
  2. $p = kill 0,$p;
  3. print "x";
  4. sleep 1 if $p;
  5. print "*";
  6. last unless $p;
  7. }

但由于某种原因它甚至没有达到第一次印刷,也从未退出.

解决方法

等待函数系列仅适用于子进程,甚至是waitpid.睡眠过程不是你的孩子,而是你孩子的孩子.这是因为系统本质上是fork exec.通过使用Parallel :: ForkManager系统,你正在分叉,然后再次分叉,然后执行睡眠.

既然你已经分叉了,你应该使用exec.这有一个额外的好处,就是不需要调用pgrep和它的计时问题(即,在子进程执行系统之前,父进程可能会调用pgrep).

  1. my $pm = Parallel::ForkManager->new(5);
  2. my $pid = $pm->start;
  3. my $p = $pid;
  4. if (!$pid) {
  5. no warnings; # no warnings "exec" is not working
  6. exec("sleep 10");
  7. $pm->finish;
  8. }
  9.  
  10. print "sleep pid is $p\n";
  11. waitpid($p,0);

为简单起见,它现在正在使用睡眠.必须抑制Perl警告“不太可能达到声明”,因为Perl没有意识到$pm-> start已经分叉.这应该是没有警告“exec”,但这不起作用所以我不得不压制它们.

猜你在找的Linux相关文章