我有一个在后台运行python脚本的Delphi服务器(它们的运行类似于“python Sync.py **params**
”)。
此脚本可以执行诸如连接到外部服务器,打开ssh连接以及可以挂起的可怕内容之类的操作。
我需要检测它们是否挂起并杀死它。此外,如果服务器已关闭,并且也想要终止进程(如果没有,则Delphi服务器挂起,从桌面消失但在后台不可见。如果再次执行服务器,这会导致问题。)
首先尝试不工作。该进程被杀死,但如果我关闭应用程序,则服务器挂起。
所以问题是,是否存在更可靠/更好的方法来杀死子进程。
现在,我保存他们的Handle和他们的GetTickCount,如下所示:“handle = tickcount”,然后每4秒运行一次TTimer并查看进程是否超时:
procedure TfrmMain.CheckProcess(Sender: TObject);
var
i: Integer;
Fecha:TDateTime;
start, stop, elapsed,Handle : cardinal;
begin
stop := GetTickCount;
for i := (FProcesos.Count - 1) downto 0 do
begin
start := StrToInt( FProcesos.ValueFromIndex[i] );
elapsed := stop - start; //milliseconds
//Esta muerto el proceso??
if ((elapsed>TIMEOUT_PROCESS) or (FTimer.Enabled=False)) then
begin
Handle := StrToInt( FProcesos.Names[i] );
TerminateProcess(Handle,0);
CloseHandle( Handle );
FProcesos.Delete( i );
LogMsg('A process timed out!',msgError);
end;
end;//for
end;
答案 0 :(得分:0)
我不明白你是如何检查一个过程是否没有响应。如果您的子进程具有GUI,则可以使用SendMessageTimeOut API函数向属于该进程的其中一个窗口发送消息,并检查该消息是否在指定时间内由其处理。
下面是一个示例代码,它使用我的TProcessInfo列出当前线程的所有子进程,并终止任何没有响应的子进程 - 请注意,因为我无法理解您的检测方法没有响应的进程,IsProcessUnResponsive函数没有在我的代码中实现,并留给你:
function IsProcessUnResponsive(const ProcessID: Cardinal): Boolean;
begin
//Use your own technique for determining if a process is not responsive.
end;
procedure TerminateUnResponsiveProcesses;
var
Process: TProcessItem;
ProcessInfo : TProcessInfo;
begin
ProcessInfo := TProcessInfo.Create(nil);
try
for Process in ProcessInfo.RunningProcesses do
begin
if Process.ParentProcessID = GetCurrentProcessId then
if IsProcessUnResponsive(Process.ProcessID) then
Process.TerminateProcess;
end;
finally
ProcessInfo.Free;
end;
end;
答案 1 :(得分:0)
调用TerminateProcess
是杀死进程的唯一可靠方法。
有更多优雅的方式,但要使用它们,您需要了解过程如何被告知关闭。 GUI进程通常希望关闭它们的主窗口,因此您需要确定它们是哪些窗口,然后向它们发送wm_Close
消息。批处理模式控制台程序可能希望您按Ctrl + C;交互式控制台程序可能有一个你应该键入的特殊命令。
并且所有这些都假定该过程仍在响应输入。如果进程挂起,它可能永远不会看到“优雅”命令,因此TerminateProcess
强制终止是唯一剩下的选项。
如果我是你,我会在错误消息中避免使用术语 zombie process 。你正在处理的不是僵尸。僵尸是已终止的进程,但其他进程仍有一个打开的句柄。您正在做的是检测运行时间过长且超时的进程。它们不一定是挂起的流程,只是占用时间超过规定时间的流程。所以只需在错误消息中说 :“进程已超时”。 (如果你能记录哪个处理的一些有意义的指示,那就更好了。)