如何判断一个进程PID是否存在???

蓝之羽520 2018-11-28 08:00:25
有一个进程PID,一开始进程存在,用OpenProcess判断,可以返回一个句柄,然后CloseHandle后,将进程PID退出,

然后再通过OpenProcess判断,有时候正常返回0,但也有返回不为0的情况,这种情况还很多,我确定进程里没有指定的进程PID。

希望大家给分析下如何判断一个进程PID是否存在,不要遍历进程,那样有点占CPU,因为我是在一个无限循环里不断检测这个PID是否存在的。
...全文
2089 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Music 爱好者 2019-06-12
  • 打赏
  • 举报
回复
//判断进程id是否存在 //@param:process_id:需要传入的进程id值 //return:True:存在,False:不存在 BOOL isExistProcess(DWORD process_id) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (INVALID_HANDLE_VALUE == hSnapshot) { return NULL; } PROCESSENTRY32 pe = { sizeof(pe) }; for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) { if (pe.th32ProcessID == process_id) { return TRUE; } } CloseHandle(hSnapshot); return FALSE; }
Csdn技术大神 2018-12-04
  • 打赏
  • 举报
回复
通过调试看出错误代码就可以了
弥了啥 2018-12-01
  • 打赏
  • 举报
回复
可以通过DOS查看哦!
赵4老师 2018-12-01
  • 打赏
  • 举报
回复
任务管理器当然也不可能一定能显示比如仅经过15ms就创建并终止的进程。
doloopcn 2018-11-30
  • 打赏
  • 举报
回复
通过进程id获取进程名称,不能获取到的为不存在
zwfgdlc 2018-11-30
  • 打赏
  • 举报
回复
如果只是监视进程退出的话,可以开一个线程用WaitForSingleObject等待进程退出
蓝之羽520 2018-11-30
  • 打赏
  • 举报
回复
引用 10 楼 zwfgdlc 的回复:
OpenProcess函数返回0,
可能是PID无效,GetLastError()返回87(无效参数)
也可能是没有权限,GetLastError()返回5
原因不一定只是进程不存在,


谢谢你的回答,虽然是答非所问
我就是想让OpenProcess函数返回0,毕竟我已经退出指定的PID进程了。

目前已经知道OpenProcess函数不能短时间内连续监测同一个PID,否则的话,即使PID的进程已经退出,OpenProcess函数也不会返回0
weixin_43884112 2018-11-30
  • 打赏
  • 举报
回复
等待进程退出就行了
  • 打赏
  • 举报
回复
引用 13 楼 doloopcn 的回复:
通过进程id获取进程名称,不能获取到的为不存在


获取到了也可能是另一个进程...
  • 打赏
  • 举报
回复
pid是可以重用的
zwfgdlc 2018-11-29
  • 打赏
  • 举报
回复
用GetLastError()看下错误代码
赵4老师 2018-11-29
  • 打赏
  • 举报
回复 1
《Windows编程启示录》
19.6 为什么有些进程在被终止之后还停留在任务管理器中
当某个进程结束时(可能是正常结束,也可能是因为调用了像TerminateProcess之类的函数),这个进程的用户态模块将被删除。但内核态模块只有在与线程相关的所有驱动程序执行完成之后才会被删除。
例如,如果某个线程正处于I/O操作中,那么将会给负责I/O的驱动程序发送一个内核信号来取消这个操作。
如果驱动程序的行为是良好的,那么它将清除与这个未完成I/O相关的一些信息并且释放线程。
如果驱动程序的行为是不好的(可能是因为驱动程序管理的硬件表现出奇怪的行为),那么可能需要花很长的时间来清除这个未完成的I/O。在这段时间里,驱动程序将不会释放这个线程(以及这个线程所在的进程)。实际的情况要更复杂一些,但这里的简单模型对于我们的讨论已经足够。
……
换句话说,如果你终止了某个进程后还能在任务管理器中看到这个进程,那么实际上这个进程已经停止运行了,只不过还有些残留的信息保留在系统中,只有当与这个进程相关的所有驱动程序都完成了清除操作并且指向这个进程的句柄都已经关闭,进程才会完全消失。
zwfgdlc 2018-11-29
  • 打赏
  • 举报
回复
OpenProcess函数返回0, 可能是PID无效,GetLastError()返回87(无效参数) 也可能是没有权限,GetLastError()返回5 原因不一定只是进程不存在,
蓝之羽520 2018-11-29
  • 打赏
  • 举报
回复
而且有次等了十几分钟都没有返回0
蓝之羽520 2018-11-29
  • 打赏
  • 举报
回复
引用 1 楼 ckc 的回复:
关了之后等一会再检测,可能关也需要一定的时间

确实,要等一会,不过等的时间有点长啊,两三分钟呢
ckc 2018-11-29
  • 打赏
  • 举报
回复
关了之后等一会再检测,可能关也需要一定的时间
蓝之羽520 2018-11-29
  • 打赏
  • 举报
回复
引用 4 楼 赵4老师 的回复:
《Windows编程启示录》
19.6 为什么有些进程在被终止之后还停留在任务管理器中
当某个进程结束时(可能是正常结束,也可能是因为调用了像TerminateProcess之类的函数),这个进程的用户态模块将被删除。但内核态模块只有在与线程相关的所有驱动程序执行完成之后才会被删除。
例如,如果某个线程正处于I/O操作中,那么将会给负责I/O的驱动程序发送一个内核信号来取消这个操作。
如果驱动程序的行为是良好的,那么它将清除与这个未完成I/O相关的一些信息并且释放线程。
如果驱动程序的行为是不好的(可能是因为驱动程序管理的硬件表现出奇怪的行为),那么可能需要花很长的时间来清除这个未完成的I/O。在这段时间里,驱动程序将不会释放这个线程(以及这个线程所在的进程)。实际的情况要更复杂一些,但这里的简单模型对于我们的讨论已经足够。
……
换句话说,如果你终止了某个进程后还能在任务管理器中看到这个进程,那么实际上这个进程已经停止运行了,只不过还有些残留的信息保留在系统中,只有当与这个进程相关的所有驱动程序都完成了清除操作并且指向这个进程的句柄都已经关闭,进程才会完全消失。


这个有道理,但不是在任务管理器里看见这个进程,而是任务管理器里面也没有这个进程,如果不间断的调用OpenProcess,间隔几十毫秒那种,即使任务管理器里面的进程已经消失了,那返回的也可能不是0,必须要间隔一分钟以上才可以再次调用OpenProcess

不知道还有别的方法来判断进程PID是否结束了?

蓝之羽520 2018-11-29
  • 打赏
  • 举报
回复
引用 6 楼 早打大打打核战争 的回复:
pid是可以重用的


我知道可以重用,但我确定这个PID没有在任务管理器里面
蓝之羽520 2018-11-29
  • 打赏
  • 举报
回复
引用 5 楼 zwfgdlc 的回复:
用GetLastError()看下错误代码

不是报错,是进程已经关掉了,OpenProcess返回的不是0,要过一两分钟后调用OpenProcess才返回0

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧