【问题标题】:How can I freeze the execution of a program?如何冻结程序的执行?
【发布时间】:2011-05-03 00:53:19
【问题描述】:

假设我有一个程序会占用处理器和/或硬盘,以至于几乎不可能在该计算机上执行任何其他操作。现在我不想杀死那个程序,因为它的作用是有用的(它是一个批处理作业,确实是 CPU 或磁盘很重,例如它可以压缩几 GB 的数据文件)但短时间内我需要做那台电脑上的其他东西。有什么方法可以让外部程序暂时冻结这个性能杀手?

这就像旧的 DOS 选项,无需实际执行多任务处理即可在程序之间切换。

假设有问题的假设程序是第 3 方产品,我没有它的源代码,也无法让它暂停。

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

我正在谈论 Windows XP 作为操作系统,并希望使用 Delphi 编写解决方案。我拥有这台机器的所有权限,所以我可以以管理员身份启动某些东西,替换文件,如果有必要,我还可以安装服务。

【问题讨论】:

标签: performance delphi windows-xp


【解决方案1】:

您可以使用Process Explorer 冻结它:右键单击您的程序并选择Suspend

以下是来自http://www.c-plusplus.de/forum/viewtopic-var-p-is-1460293.html 的一些程序冻结示例代码,为简洁起见,已编辑并省略了错误检查:

#include <windows.h>

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

【讨论】:

【解决方案2】:

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

它的作用是枚举一个进程中的所有线程,然后将它们挂起。没有 SuspendProcess API,所以这是对这种调用的模拟。

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

我不知道在 Win32/64 API 世界中有任何其他方法可以做到这一点。如果您深入内核领域并使用 NT* API,则您可以使用“NtSuspendProcess”API。但这是未记录的,因此它可以随任何版本的 Windows 甚至任何服务包而改变(虽然不太可能)。

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

【讨论】:

    【解决方案3】:

    您可以使用我的ProcessInfo 组件来挂起属于该进程的所有线程。该方法类似于 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;
    

    您可以从here下载ProcessInfo源代码

    【讨论】:

    • 我接受你的回答,尽管其他人也是正确的并且包含更多关于细节的信息,但我很懒,所以我喜欢使用组件。
    • @vcldeveloper,这与 resmon stackoverflow.com/a/21649539/632951 有何不同?
    【解决方案4】:
    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;
    

    希望对你有帮助

    【讨论】:

    • 使用 tlhelp32; (在你的使用条款中添加这个)
    猜你喜欢
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多