perl fork()exec(),子进程变得疯狂 [英] perl fork() exec() , child process gone wild
问题描述
我正在使用Linux
,而.sh
在tcsh
中.
I am using Linux
and .sh
is in tcsh
.
我做了一个非常基本的叉子和
I have made a very basic fork and exec, but I need help in implementing safeties to it.
基本上,我的perl脚本在子进程中调用.sh
脚本.但是当我Ctrl+c
杀死父母时,孩子会忽略该信号.
Basically my perl script calls a .sh
script in a child process. But when I do Ctrl+c
to kill the parent, the signal gets ignored by the child.
1)我如何也捕获子进程的SIGINT
?
1) How do I capture the SIGINT
for the child process as well?
2)运行.sh脚本的子进程仍然STDOUT到xterm的屏幕.我该如何删除?我当时正在考虑在后台运行脚本
2) The child process that runs the .sh script still STDOUT to the screen of the xterm. How can I remove this? I was thinking of doing running the script in the background
exec("shell.sh args &");
但是还没有进行测试,因为我需要弄清楚如何防止孩子先变得疯狂.
But haven't tested as I need to figure out how to keep the child from going wild first.
3)父进程(perl脚本)不等待子进程(.sh脚本).所以我读了很多关于孩子成为僵尸的信息???脚本完成后会发生吗?而我将如何停止呢?
3) The parent process(perl script) doesn't wait on the child(.sh script). So I've read a lot about the child becoming a zombie??? Will it happen after the script is done? And how would I stop it?
$pid = fork();
if($pid < 0){
print "Failed to fork process... Exiting";
exit(-1);
}
elsif ($pid ==0) {
#child process
exec("shell.sh args");
exit(1);
}
else { #execute rest of parent}
推荐答案
但是当我执行ctrl + c杀死父级时,子级会忽略该信号.
But when I do ctrl+c to kill the parent, the signal gets ignored by the child.
信号被发送给父母和孩子两个.
The signal is sent to two both the parent and the child.
$ perl -E'
if (my $pid = fork()) {
local $SIG{INT} = sub { say "Parent got SIGINT" };
sleep;
waitpid($pid, 0);
} else {
local $SIG{INT} = sub { say "Child got SIGINT" };
sleep;
}
'
^CParent got SIGINT
Child got SIGINT
如果那个孩子忽略了它,那是因为它开始了一个新的会话,或者是因为它明确地忽略了它.
If that child ignores it, it's because it started a new session or because it explicitly ignores it.
运行.sh脚本的子进程仍然STDOUT到xterm的屏幕.我该如何删除呢?
The child procces that runs the .sh script still STDOUT to the screen of the xterm. How can I remove this?
在调用exec
之前在孩子中执行以下操作:
Do the following in the child before calling exec
:
open(STDOUT, '>', '/dev/null');
open(STDERR, '>', '/dev/null');
实际上,我会使用 open3
进行一些错误检查. /p>
Actually, I would use open3
to get some error checking.
open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
open(local *CHILD_STDOUT, '>', '/dev/null') or die $!;
my $pid = open3(
'<&CHILD_STDIN',
'>&CHILD_STDOUT',
'>&CHILD_STDOUT',
'shell.sh', 'args',
);
父进程(perl脚本)不等待子进程(.sh脚本).所以我读了很多关于孩子成为僵尸的故事?
The parent process(perl script) doesn't wait on the child(.sh script). So I've read alot about the child becoming a zombie???
孩子在父母退出时或在父母退出后退出时会自动获得收成.
Children are automatically reaped when the parent exits, or if they exit after the parent exits.
$ perl -e'
for (1..3) {
exec(perl => (-e => 1)) if !fork;
}
sleep 1;
system("ps");
' ; ps
PID TTY TIME CMD
26683 pts/13 00:00:00 bash
26775 pts/13 00:00:00 perl
26776 pts/13 00:00:00 perl <defunct> <-- zombie
26777 pts/13 00:00:00 perl <defunct> <-- zombie
26778 pts/13 00:00:00 perl <defunct> <-- zombie
26779 pts/13 00:00:00 ps
PID TTY TIME CMD
26683 pts/13 00:00:00 bash
26780 pts/13 00:00:00 ps
<-- all gone
如果父母先于孩子退出,那就没问题了.
If the parent exits before the children do, there's no problem.
如果父母在孩子们离开后不久就退出了,那就没问题了.
If the parent exits shortly after the children do, there's no problem.
如果父母在孩子离开后很长时间退出了,您将希望获得他们的收获.您可以使用wait
或waitpid
(可能来自SIGCHLD
处理程序)来执行此操作,也可以使用$SIG{CHLD} = 'IGNORE';
使它们自动收割.参见 perlipc .
If the parent exits a long time after the children do, you'll want to reap them. You could do that using wait
or waitpid
(possibly from a SIGCHLD
handler), or you could cause them to be automatically reaped using $SIG{CHLD} = 'IGNORE';
. See perlipc.
这篇关于perl fork()exec(),子进程变得疯狂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!