终止在 Perl 中使用 system() 启动的应用程序
我正在尝试使用 system()
在 Perl 脚本中运行应用程序。我正在运行的应用程序有时会卡住(它进入某种无限循环)。有没有办法让我知道这个应用程序是否卡住并终止它以继续执行 Perl 脚本?
我正在尝试做这样的事情:
start testapp.exe;
if(stuck with testapp.exe) {
kill testapp.exe;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
确定是否“陷入无限循环”被称为停止问题并且是不可判定的。
如果您想终止它,则必须使用
fork
分叉该应用程序,然后从另一个分叉中终止它(如果该应用程序运行时间太长)。可以
您至少 根据此手册页
我不确定它在各种系统上的效果如何,你可以尝试一下。
不是直接的答案,但如果您想轻松分叉,我可以建议使用
forks
模块,但它仅在 UNIX 系统上工作(不)视窗)。好的,更多帮助代码:) 它在 UNIX 中工作,根据 perlfork perldoc,它在 Windows 上的工作方式应该完全相同。
Determining if "it is stuck in infinite loop" is called Halting Problem and is undecidable.
If you want to kill it, you will have to fork the application using
fork
and then kill it from the other fork, if it is going for too long.You can determine if the proccess is going for too long by this
at least, according to this manual page
I am not sure how well it works on various systems, you can try it out.
Not a direct answer, but I can recommend using
forks
module if you want to fork with ease, but it works only on UNIX systems (not windows).OK, more helping code :) It works in UNIX, according to perlfork perldoc, it should work on Windows exactly the same way.
是
Perl 的缩写,只知道
cmd
;它不知道任何关于start
的信息,更不用说关于testapp
了。system
不是您想要的工具。这是第一个问题。第二个问题是你还没有定义什么是“卡住”。如果你想监控一个程序,它就需要一个心跳。心跳是一种可以从外部检查的周期性活动。它可以写入管道。它可以更改文件。任何事物。
监控程序会监听此心跳,如果心脏停止跳动,则认为程序已死亡,可以这么说。
“杀死”是使用unix中的信号完成的,但它是使用
TerminateProcess
。第三个问题是 Perl 核心不允许您访问该函数。第一个问题和第三个问题的解决方案是Win32::Process。它允许您在后台启动进程,也允许您终止它。
创建心跳由您决定。
is short for
Perl just knows about
cmd
; it doesn't know anything aboutstart
, much less abouttestapp
.system
is not the tool you want. That's the first problem.The second problem is that you haven't defined what it means to be "stuck". If you want to monitor a program, it needs a heartbeat. A heartbeat is a periodic activity that can be externally examined. It can be writing to a pipe. It can be changing a file. Anything.
The monitoring program listens for this heartbeat, and presumes the program is dead if the heart stops beating, so to speak.
"Killing" is done using signals in unix, but it's done using
TerminateProcess
in Windows. The third problem is that Perl core does not give you access to that function.The solution to the first and third problem is Win32::Process. It allows you to launch a process in the background, and it also allows you to terminate it.
Creating a heartbeat is up to you.
如果您知道 testapp 不应该花费超过 N 秒的时间来完成其操作,那么您可以通过以下方式处理该问题: IPC::Run。
在下面的示例中,超时为 1 秒,它会终止耗时过长(长于 1 秒超时)的
sleep 10
命令。如果这没有达到您想要的效果,那么您应该提供有关如何检测 testapp.exe“卡住”的更多信息。Here is one way you can handle the problem if you know that testapp should not take more than N seconds to do its thing, then you can use a timeout to kill the app by way of IPC::Run.
In the example below there is a timeout of 1 second which kills the
sleep 10
command that takes too long (longer than the timeout of 1 second). If this doesn't do what you want, then you should provide more information about how you can detect that testapp.exe is "stuck".如果您这样执行,则无法确定应用程序已卡住,因为在应用程序终止之前
system
语句不会返回。因此,至少您需要启动测试应用程序,以便它可以从监视它的 Perl 脚本异步运行。
解决了这部分问题后,您必须建立一种机制,允许监视 Perl 脚本确定应用程序是否卡住。这是一个不简单的练习,并且可能依赖于系统,除非您采用简单的权宜之计,例如要求应用程序在某处写入心跳指示,并且 Perl 脚本监视心跳。例如(不一定是一个好的例子),应用程序可以将当前时间写入由其 PID 标识的文件中,并且 Perl 脚本可以监视该文件以查看心跳是否足够新。当然,这假设“无限循环”不包括写入心跳文件的代码。
You can't determine that the application is stuck if you execute it like that, because the
system
statement won't return until the application terminates.So, at least, you need to start the test application so it can run asynchronously from the Perl script that is to monitor it.
Having resolved that part of the problem, you have to establish a mechanism that will allow the monitoring Perl script to determine that the application is stuck. That is a non-trivial exercise, and likely system dependent, unless you adopt a simple expedient such as requiring the application to write a heart-beat indication somewhere, and the Perl script monitors for the heart-beat. For example (not necessarily a good example), the application could write the current time into a file identified by its PID, and the Perl script could monitor the file to see if the heart-beat is sufficiently recent. Of course, this assumes that the 'infinite loop' doesn't include code that writes to the heart-beat file.