如何在父进程为 killed/finished 时保持子进程处于活动状态(在 windows 中)
How to keep child process active when parent is killed/finished (in windows)
我实际上是在创建一个脚本,其中fork()
创建一个在后台运行的子进程,并在前台检查主脚本(父进程)的时间段,运行 ,使用其进程 ID。如果主脚本(父进程)超过阈值时间,则action/s将被占用。
在Linux中,它的实现是因为 INIT 进程在主脚本(父进程)被杀死或完成后成为活动子进程(孤立进程)的父进程。
但是,我无法在 Windows 中实现它,因为父子架构不同于 Linux。
在 Perl 语言下(在 Linux 中)的简码是:
sub run_sleep {
my $pid = fork(); ## Here, $pid var. will have child process PID for parent, and value 0 for child process
return if $pid; # returns to the parent process( out of function)
print "Running child process\n"; # Proceeds for the child process
select undef, undef, undef, $initial_time_wait ;
if ( kill 0, $Parent_ID ) { ##Here, $Parent_ID is main script id (parent process id)
print "Parent process $Parent_ID_or_script_id still exists\n";
}
else {
print "Parent process $Parent_ID_or_script_id must have completed";
exit 0;
}
print "Done with child process\n";
exit 0; # end child process
}
如何为 Windows 实现这个?
Windows 不提供分叉机制。 Perl 使用线程提供有限的模拟。由于没有创建子进程,所以没有子进程保持存活。
您也许可以使用类似下面的内容(但您需要将任何相关状态传达给子级,因为它不是父级的副本):
if (@ARGV && $ARGV[0] eq "!fork!") {
shift(@ARGV);
child();
exit;
}
...
my $pid;
if ($^O eq 'Win32') {
$pid = system(-1, $^X, '--', [=10=], "!fork!", ...args...);
} else {
...
}
- 在Windows中,当你杀死parent进程时,它的children也会被杀死。 (不像 Linux,在 parent 被杀死后,children 得到他们新的 parent -INIT 和 PID 1)。
- 在windows中,如果child仍然是运行,parent也不会自动退出(parent PID会存在)。 (针对您的问题)。
所以,解决方案是在主脚本结束之前添加一个步骤,child PID 被杀死;所以当child被杀死时,parent也能成功退出。
因此,现在如果您的主脚本在阈值时间之前完成,则意味着 child 不需要任何操作(而且,child 将在主脚本完成之前被终止)。如果主脚本超过阈值,child 将发送一封邮件。而当主脚本即将结束时,child会先被kill掉,主脚本才能成功退出。
我实际上是在创建一个脚本,其中fork()
创建一个在后台运行的子进程,并在前台检查主脚本(父进程)的时间段,运行 ,使用其进程 ID。如果主脚本(父进程)超过阈值时间,则action/s将被占用。
在Linux中,它的实现是因为 INIT 进程在主脚本(父进程)被杀死或完成后成为活动子进程(孤立进程)的父进程。
但是,我无法在 Windows 中实现它,因为父子架构不同于 Linux。
在 Perl 语言下(在 Linux 中)的简码是:
sub run_sleep {
my $pid = fork(); ## Here, $pid var. will have child process PID for parent, and value 0 for child process
return if $pid; # returns to the parent process( out of function)
print "Running child process\n"; # Proceeds for the child process
select undef, undef, undef, $initial_time_wait ;
if ( kill 0, $Parent_ID ) { ##Here, $Parent_ID is main script id (parent process id)
print "Parent process $Parent_ID_or_script_id still exists\n";
}
else {
print "Parent process $Parent_ID_or_script_id must have completed";
exit 0;
}
print "Done with child process\n";
exit 0; # end child process
}
如何为 Windows 实现这个?
Windows 不提供分叉机制。 Perl 使用线程提供有限的模拟。由于没有创建子进程,所以没有子进程保持存活。
您也许可以使用类似下面的内容(但您需要将任何相关状态传达给子级,因为它不是父级的副本):
if (@ARGV && $ARGV[0] eq "!fork!") {
shift(@ARGV);
child();
exit;
}
...
my $pid;
if ($^O eq 'Win32') {
$pid = system(-1, $^X, '--', [=10=], "!fork!", ...args...);
} else {
...
}
- 在Windows中,当你杀死parent进程时,它的children也会被杀死。 (不像 Linux,在 parent 被杀死后,children 得到他们新的 parent -INIT 和 PID 1)。
- 在windows中,如果child仍然是运行,parent也不会自动退出(parent PID会存在)。 (针对您的问题)。
所以,解决方案是在主脚本结束之前添加一个步骤,child PID 被杀死;所以当child被杀死时,parent也能成功退出。
因此,现在如果您的主脚本在阈值时间之前完成,则意味着 child 不需要任何操作(而且,child 将在主脚本完成之前被终止)。如果主脚本超过阈值,child 将发送一封邮件。而当主脚本即将结束时,child会先被kill掉,主脚本才能成功退出。