Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何冻结程序的执行?_Performance_Delphi_Windows Xp - Fatal编程技术网

Performance 如何冻结程序的执行?

Performance 如何冻结程序的执行?,performance,delphi,windows-xp,Performance,Delphi,Windows Xp,假设我有一个程序占用了处理器和/或硬盘,以至于几乎不可能在这台计算机上做任何其他事情。现在我不想杀掉这个程序,因为它所做的是有用的,它是一个批处理作业,实际上CPU或磁盘很重,例如,它可以压缩几GB的数据文件,但在很短的时间内,我需要在那台计算机上做些其他的事情。外部程序有没有办法暂时冻结这个性能杀手 这就像旧的DOS选项一样,可以在程序之间切换,而不需要进行多任务处理 假设所讨论的假设程序是第三方产品,我没有该产品的源代码,也无法告诉它暂停 我知道我可以更改程序的优先级,例如在TaskMana

假设我有一个程序占用了处理器和/或硬盘,以至于几乎不可能在这台计算机上做任何其他事情。现在我不想杀掉这个程序,因为它所做的是有用的,它是一个批处理作业,实际上CPU或磁盘很重,例如,它可以压缩几GB的数据文件,但在很短的时间内,我需要在那台计算机上做些其他的事情。外部程序有没有办法暂时冻结这个性能杀手

这就像旧的DOS选项一样,可以在程序之间切换,而不需要进行多任务处理

假设所讨论的假设程序是第三方产品,我没有该产品的源代码,也无法告诉它暂停

我知道我可以更改程序的优先级,例如在TaskManager中,但这还不够,我想冻结它

我说的是Windows XP作为操作系统,我想用Delphi编写一个解决方案。我拥有这台机器的所有权限,因此我可以作为管理员启动一些程序,替换文件,如果有必要,我还可以安装一项服务。

您可以通过以下方法将其冻结:右键单击您的程序并选择“挂起”

以下是一些示例代码,用于从中进行编程冻结、编辑和省略错误检查,以确保简洁性:

#include <windows.h>

_NtSuspendProcess NtSuspendProcess =
    (_NtSuspendProcess) GetProcAddress( GetModuleHandle( "ntdll" ),
                                        "NtSuspendProcess" ); 
HANDLE ProcessHandle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid);
NtSuspendProcess( ProcessHandle );

如果您想以编程的方式进行,您可以使用所描述的方法

它所做的是枚举进程中的所有线程,然后挂起它们。没有SuspendProcess API,因此这是对此类调用的模拟

请注意,这可能会产生一些不良副作用。这取决于流程和编写方式

在Win32/64 API世界中,我不知道还有其他方法可以做到这一点。如果您走到内核的底层并使用NT*API,那么就有了可用的NtSuspendProcess API。但这是没有文档记录的,因此它可以在任何版本的windows中更改,甚至在任何service pack中更改,但可能性不大

NtSuspendProcess的声明可以在windows API的JEDI端口中找到

function OpenThread(dwDesiredAccess: DWORD; InheritHandle: Boolean; dwThreadID: DWORD): THandle; stdcall; external 'kernel32.dll';

function ResumeProcess(PID: DWORD):Boolean;
var
  tid, snap: THandle;
  TE32: TThreadEntry32;
begin
  Result := False;
  snap := CreateToolHelp32SnapShot(TH32CS_SNAPTHREAD, 0);
  TE32.dwSize := SizeOf(TThreadEntry32);
  Thread32First(snap, TE32);
  repeat
    if TE32.th32OwnerProcessID = PID then begin
      tid := OpenThread($0002, FALSE, TE32.th32ThreadID);
      ResumeThread(tid);
      Result := TRUE;
      CloseHandle(tid);
    end;
  until Thread32Next(snap, TE32) = false;
  CloseHandle(snap);
end;

function SuspendProcess(PID: DWORD): Boolean;
var
  tid, snap: THandle;
  TE32: TThreadEntry32;
begin
  Result := False;
  snap := CreateToolHelp32SnapShot(TH32CS_SNAPTHREAD, 0);
  TE32.dwSize := SizeOf(TThreadEntry32);
  Thread32First(snap, TE32);
  repeat
    if TE32.th32OwnerProcessID = PID then begin
      tid := OpenThread($0002, FALSE, TE32.th32ThreadID);
      SuspendThread(tid);
      Result := TRUE;
      CloseHandle(tid);
    end;
  until Thread32Next(snap, TE32) = false;
  CloseHandle(snap);
end;
希望这有帮助

您可以使用我的组件挂起属于该进程的所有线程。该方法类似于Runner向您解释的方法。代码如下所示:

var
  Process : TProcessItem;
  AThread: TThreadItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe');
  if Assigned(Process) then
  begin
    for AThread in Process.Threads do
      AThread.SuspendThread;
  end;
end;

您可以下载表单的源代码

啊是的,但它使用的是什么API调用?所有进程线程上的SuspendThread?知道Russinovich和他对内核的了解,它可能直接使用NtsupendProcess。这里的英文文本@Runner Thank,为NtsupendProcess添加了一些示例代码@belisarius Thank,编辑了我的链接指向英文版本。使用tlhelp32;将此添加到您的uses子句中我接受您的答案,即使其他答案也正确,并且包含有关细节的更多信息,但我很懒,所以我喜欢使用组件。@vcldeveloper,这与resmon有何不同?对于使用DebugActiveProcess的替代解决方案: