gpt4 book ai didi

Perl kill子进程也退出父进程?

转载 作者:行者123 更新时间:2023-12-04 02:16:50 28 4
gpt4 key购买 nike

我正在用 PERL 编写仿真 stub 来测试另一个程序。下面,代码运行一个循环来检查命令(初始化、退出、start_trace、stop_trace)。当读取“start_trace”命令时,它会 fork 一个每秒只吐出数字的进程。我想用“stop_trace”杀死 child ,但它也杀死了 parent 。我错过了什么?

use warnings;
use strict;

my $pid = undef;

$| = 1;

$SIG{TERM} = sub {
if ($pid == 0) {
print "Parent, not terminating\n";
} else {
print "Child ($pid) terminating\n";
exit(1);
}
};


print "entering loop\n";
while (1) {
while (<>) {
my ($command, @args) = split();
if ($command eq "exit") {
exit 1;
}
elsif ($command eq "initialize") {
print "s: ok\n";
}
elsif ($command eq "start_trace") {
if (defined $pid) {
print "child already running\n";
} else {
$pid = fork();
if ($pid == -1) {
print "failed to fork\n";
exit 1;
}
elsif ($pid == 0) {
print "Parent\n";
}
else {
my $timestamp = 0;
while (1) {
for (my $i = 0; $i < 12; ++$i) {
printf "%.3f %.0f %.2f %.1f\n",
++$timestamp,
0,
0,
100 * rand()
;
}
sleep(1);
}
}
}
}
elsif ($command eq "stop_trace") {
kill "TERM", $pid;
#waitpid($pid, 0);
$pid = undef;
}
else {
printf "s: unknown command $command\n";
}
}
}

输出(不是 stdin 和 stdout 都混合在一起,但我输入的是“stop_trace”)

stop85.000 0 0.00 66.6
86.000 0 0.00 43.3
87.000 0 0.00 82.3
88.000 0 0.00 62.8
89.000 0 0.00 43.5
90.000 0 0.00 50.0
91.000 0 0.00 8.8
92.000 0 0.00 89.3
93.000 0 0.00 61.4
94.000 0 0.00 92.4
95.000 0 0.00 46.6
96.000 0 0.00 53.9
_trace
Child (26644) terminating
Parent, not terminating
%

但他们都退出了!为什么?

最佳答案

我认为这里有一个逻辑错误 - 当你 fork()发生的是两位代码分支——唯一的区别是子进程有一个来自 fork() 的返回码。为零,他的返回码为$pid .

It returns the child pid to the parent process, 0 to the child process, or undef if the fork is unsuccessful.

所以我认为你测试的时候逻辑是倒退的:

elsif ($pid == 0) {
print "Parent\n";
}

实际上是您的 父进程 进入了 while 循环,而您的子进程仍在 while 循环中读取标准输入。

我认为这就是您遇到问题的原因 - 因为 child 正在捡起 stop_trace并发出 kill "TERM", 0应该被杀死,而不是 child pid。

我实际上并不完全确定当您杀死 pid 0 时应该发生什么。但从它的外观来看 - 它无论如何都会向两个进程发出信号。

而且你的信号处理程序中有相同的逻辑错误 - 你的 parent 被杀了,因为它有 $pid设置为 0 .我不是 100% 确定为什么这会导致你的 child 退出 - 你确定它真的是,而且你没有在 while(1) 中积累陈旧的进程关闭STDIN

虽然很容易检查 - 贴上 print "$$: killing child with pid $pid\n";在那stop_trace分支。

哦 - 还有 fork在 perl 中返回 undef不是 -1如果失败了。

关于Perl kill子进程也退出父进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33321555/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com