世界杯门票_托马斯穆勒世界杯进球数 - noh16.com

世界杯门票_托马斯穆勒世界杯进球数 - noh16.com

shape
  • Home
  • 乌拉圭世界杯冠军
  • windows下的进程监测

windows下的进程监测

  • 2026-01-13 21:24:31
  • admin

在Windows系统中,监测进程的退出可以通过多种方法实现,具体选择取决于应用场景、性能需求和开发复杂度。以下是几种常见且有效的方法,按适用场景分类说明:

1. 使用 WaitForSingleObject 或 WaitForMultipleObjects(同步阻塞)

原理:通过等待进程句柄(PROCESS对象)的信号状态,当进程终止时,句柄变为“有信号”状态,函数返回。

适用场景:

需要同步阻塞当前线程,直到目标进程退出。

适用于简单的进程监控(如父进程等待子进程退出)。

代码示例:

c

#include

#include

int _tmain(int argc, TCHAR *argv[]) {

STARTUPINFO si = { sizeof(si) };

PROCESS_INFORMATION pi;

// 创建子进程

if (!CreateProcess(NULL, _T("child.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {

_tprintf(_T("CreateProcess failed (%d)\n"), GetLastError());

return 1;

}

// 等待子进程退出(无限超时)

DWORD exitCode;

WaitForSingleObject(pi.hProcess, INFINITE);

GetExitCodeProcess(pi.hProcess, &exitCode);

_tprintf(_T("Child process exited with code %d\n"), exitCode);

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

return 0;

}

优点:

简单直接,无需轮询。

缺点:

阻塞当前线程,无法同时监控多个进程。

2. 使用 Job Object(批量监控多进程)

原理:将进程关联到作业对象(Job Object),通过作业对象的通知机制(如JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT或自定义消息)监控进程退出。

适用场景:

需要批量监控多个进程的退出。

适用于进程管理工具或沙箱环境。

关键步骤:

创建作业对象(CreateJobObject)。

将进程句柄分配到作业(AssignProcessToJobObject)。

设置作业通知(需通过IOCP或自定义轮询,因Windows未直接提供进程退出通知)。

代码示例(简化版):

c

HANDLE hJob = CreateJobObject(NULL, NULL);

AssignProcessToJobObject(hJob, pi.hProcess);

// 需结合IOCP或轮询监控作业状态(复杂,此处省略)

优点:

高效管理多进程。

缺点:

实现复杂,需处理作业对象的其他限制(如资源限制)。

3. 使用 ReadDirectoryChangesW 监控进程文件句柄(高级技巧)

原理:通过监控系统目录(如\Sessions\1\BaseNamedObjects)中进程相关内核对象的变化,间接检测进程退出(需管理员权限,且不可靠)。

适用场景:

仅作为理论参考,不推荐生产环境使用。

4. 使用 Windows 事件追踪(ETW)或 WMI(复杂但强大)

原理:

ETW:通过订阅Process提供程序的事件(如ProcessStart和ProcessStop)监控进程生命周期。

WMI:查询Win32_Process类的TerminationDate属性(需轮询)。

适用场景:

需要全局监控所有进程的退出(如系统监控工具)。

代码示例(WMI,C#):

csharp

using System.Management;

var watcher = new ManagementEventWatcher(

"SELECT * FROM Win32_ProcessStopTrace");

watcher.EventArrived += (sender, e) => {

Console.WriteLine($"Process exited: {e.NewEvent["ProcessName"]}");

};

watcher.Start();

Console.ReadLine();

优点:

功能强大,支持全局监控。

缺点:

实现复杂,性能开销较高。

5. 使用 CreateRemoteThread + 回调(主动轮询)

原理:在目标进程中注入线程,定期检查进程状态(如OpenProcess + GetExitCodeProcess),但通常不推荐(破坏性操作)。

6. 最佳实践推荐

场景推荐方法原因

父进程等待子进程退出

WaitForSingleObject

简单直接,阻塞等待。

监控多个独立进程的退出

轮询 + CreateToolhelp32Snapshot

无需复杂机制,代码可控。

全局监控所有进程的退出

WMI 或 ETW

功能全面,但实现复杂。

批量管理进程组

Job Object

高效管理多进程,但需处理作业限制。

7. 完整代码示例:轮询监控进程(C++)

c

#include

#include

#include

#include

bool IsProcessRunning(DWORD pid) {

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);

if (hProcess == NULL) return false;

DWORD exitCode;

GetExitCodeProcess(hProcess, &exitCode);

CloseHandle(hProcess);

return exitCode == STILL_ACTIVE;

}

void MonitorProcesses(const std::vector& pids) {

while (true) {

for (DWORD pid : pids) {

if (!IsProcessRunning(pid)) {

_tprintf(_T("Process %d exited.\n"), pid);

// 移除已退出的进程(可选)

}

}

Sleep(1000); // 1秒轮询一次

}

}

int _tmain() {

// 示例:监控PID为1234和5678的进程

MonitorProcesses({1234, 5678});

return 0;

}

8. 注意事项

权限问题:

监控其他用户的进程可能需要管理员权限。

性能开销:

频繁轮询(如Sleep(10))可能增加CPU占用,建议调整轮询间隔。

进程复用:

PID可能被复用,需结合进程名或其他属性确认。

64位/32位兼容性:

跨平台监控时需注意句柄和PID的位数差异。

总结

简单场景:优先使用WaitForSingleObject(阻塞)或轮询(非阻塞)。

复杂场景:选择Job Object、WMI或ETW。

避免方法:不推荐使用内核对象监控或远程线程注入。

根据需求选择最合适的方法,平衡稳定性、性能和开发复杂度。

<<<
Previous Post
中国上古十大魔剑(上古十大魔剑的名字)

Copyright © 2088 世界杯门票_托马斯穆勒世界杯进球数 - noh16.com All Rights Reserved.

友情链接