Perl命令行解释器没有退出

时间:2013-11-25 20:45:06

标签: windows perl winapi hang

我在Windows中运行调用可执行文件的Perl脚本:

 $command = "$path_to_exe -i $dir -o $results";
 my $pid = fork();

    if ( !$pid ) {
        system($command);

        #do stuff

    } else {
        #do stuff
    }

 print "Exiting..."
 exit;

而不是退出之后,perl.exe只是空闲。然后弹出窗口告诉我“Perl命令行解释器已停止工作。”

我对Windows中的流程管理知之甚少,之前我在此论坛上已经阅读过使用fork()exec()并不是一个好习惯,但是除了口译员不关闭部分。我试过在Unix中尝试实现程序(它提供相同的错误),尝试使用Win32::Process命令 - 但没有任何作用。我希望可能有一个更简单的解决方案,可以让我保留我已经写过的内容。

如果有人能够在运行此代码时解释Windows中究竟发生了什么,那也是一种帮助!

3 个答案:

答案 0 :(得分:4)

我可以看到2个独立的问题。

  1. system()会创建一个子进程,因此如果您从分叉的子进程中调用system(),则会有3个进程。但是你只杀掉第二个(分叉的孩子),而孩子的孩子($命令)却没有。尝试使用像exec()这样的函数,在unix上它启动实际进程的地方(和pid)上的子进程。如果运气好的话,Windows上的Perl会做同样的事情。

  2. 您杀死$$的父线程中的
  3. ,这是当前进程。可能你想杀死$pid(这是父线程上子进程的pid)。

答案 1 :(得分:1)

我使用了以下内容(它超出了程序,最重要的是,它不会破坏Perl解释器!):

use Win32::Job;
my $job = Win32::Job->new;

   # Run $command for $max_time
   $job->spawn($Config{"path/cmd.exe"},  $command);
   $job->run($max_time);
   exit;

答案 2 :(得分:1)

在我的情况下,我删除了一些"使用"声明,它解决了。 这可能是因为" fork"的perl实现。在Windows上并不完美,并且在导入一些" heavy"对象,如OLE库。

我删除的确切用途:

#use Win32::OLE qw(in with);
#use Win32::OLE::Const 'Microsoft Excel';

解决方法:如果可能,请尝试在代码中没有fork之后动态导入库。

我的案例:

# code with fork
eval "use Win32::OLE::Const 'Microsoft Excel';";
eval "use Win32::OLE qw(in with);";
# code without fork