如何在父进程被杀死/完成时保持子进程处于活动状态(在 Windows 中)

Posted

技术标签:

【中文标题】如何在父进程被杀死/完成时保持子进程处于活动状态(在 Windows 中)【英文标题】:How to keep child process active when parent is killed/finished (in windows) 【发布时间】:2021-09-16 04:55:06 【问题描述】:

我实际上是在创建一个脚本,其中fork() 创建了一个在后台运行的子进程,并使用其进程 ID 检查在前台运行的主脚本(父进程)的时间段。如果主脚本(父进程)超过阈值时间,则将采取行动。

在 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 上实现这个?

【问题讨论】:

在同一进程中使用新线程可能是实现某种看门狗的更简单方法。 显然在 perl "Windows implementations of Perl emulate forking using threads" 这就是为什么杀死父进程会杀死子进程,从技术上讲,它们都是同一个进程。您可能需要找到一种方法来在 Windows 而不是线程上生成完整的进程。 ***.com/questions/45792/… 【参考方案1】:

Windows 不提供分叉机制。 Perl 使用线程提供有限的模拟。由于没有创建子进程,因此没有子进程可以保持活动状态。

您也许可以使用类似以下的内容(但您需要将任何相关状态传达给孩子,因为它不是父母的副本):

if (@ARGV && $ARGV[0] eq "!fork!") 
   shift(@ARGV);
   child();
   exit;


...

my $pid;
if ($^O eq 'Win32')  
   $pid = system(-1, $^X, '--', $0, "!fork!", ...args...);
 else 
   ...

【讨论】:

【参考方案2】:
    在 Windows 中,当您终止父进程时,它的子进程也会被终止。 (不像 Linux,在父节点被杀死后,子节点将获得新的父节点 -INIT,PID 为 1)。 在 Windows 中,如果子进程仍在运行,父进程也不会自动退出(将存在父进程 PID)。 (针对您的问题)。

因此,解决方案是在主脚本结束之前添加一个步骤,将子 PID 杀死;这样当孩子被杀死时,父母也可以成功退出。

所以,现在如果您的主脚本在阈值时间之前完成,这意味着孩子不需要任何操作(而且,孩子将在主脚本完成之前被杀死)。如果主脚本越过阈值,子进程就会发送邮件。而当主脚本即将结束时,会先杀死child,然后主脚本才能成功退出。

【讨论】:

以上是关于如何在父进程被杀死/完成时保持子进程处于活动状态(在 Windows 中)的主要内容,如果未能解决你的问题,请参考以下文章

如何在父进程被终止的情况下保持子进程的活力

在子进程处于活动状态时读取子进程的输出

非阻塞等待子进程退出

从烧瓶启动分离过程

检查子进程是不是处于活动状态(Windows、C++)

当父进程被杀死时,使用 fork() 创建的子进程是不是会自动被杀死?