Windows viaC/C++:终止进程
来源:互联网 发布:本地音乐播放器 知乎 编辑:程序博客网 时间:2024/05/18 00:23
结束进程
进程可以以4种方式结束:
- 主线程入口点函数(_tmain/_tWinMain)返回时结束,建议所有进程都以这种方式结束
- 进程中的某线程调用了ExitThread函数,应当避免这种情况
- 另一进程中的某线程调用了TerminateProcess函数,应当避免这种情况
- 进程中的所有线程中止,这种情况比较罕见
下面我们来分别讨论这4种情形。
主线程入口点函数返回
在设计应用程序时,你应该保证其进程只有在主线程入口点函数返回时才终止,这也是确保能够正确释放主线程使用的所有资源的唯一途径。主线程入口点函数正常返回时,系统将会执行下面的动作:
- 主线程创建的所有C++对象将被正确的销毁
- 主线程堆栈占用的内存空间将被释放
- 系统会把入口点函数的返回值作为进程的退出码写入进程内核对象中
- 进程/主线程内核对象引用计数减1
调用ExitProcess函数
当进程中的任意线程调用ExitProcess函数时,进程将被终止。我们在前面的章节提过,C/C++运行时启动函数在主线程入口点函数(WinMain、wWinMain、main或wmain)返回时,会清理进程使用的所有C运行时资源,然后显式调用ExitProcess,并将入口点函数的返回值传给ExitProcess。这也解释了主线程入口点函数返回会导致进程中止的原因,注意此时进程中的所有线程也会随进程一起终止。
根据Windows PlatformSDK文档的说法,当进程中仍然有线程在执行时,进程不会终止。对于操作系统而言这是正确的,可是C/C++运行时的实现却并非如此:当主线程入口点函数返回时,无法有进程中是否有其它正在执行的线程,进程都会被ExitProcess函数终止。然而如果你在入口点函数中调用了ExitThread而不是将其返回或调用ExitProcess,主线程会停止执行,但进程会一直存在直到其中最后一个线程中止。
调用ExitThread和ExitProcess会导致线程或进程在函数内立刻终止,对于操作系统来说这无关紧要,因为系统会保证释放线程/进程用到的系统资源,但是,C/C++程序应该避免调用这些函数,C/C++运行时可能无法及时执行清理工作,比如下面的代码:
- #include
- #include
-
- class
CSomeObj { - public:
-
CSomeObj() { printf( } -
~CSomeObj() { printf( } - };
-
-
- CSomeObj
g_GlobalObj; -
- void
main () { -
CSomeObj LocalObj; -
ExitProcess(0); This shouldn't be here -
-
At the end of this function, the compiler automatically added -
the code necessary to call LocalObj's destructor. -
ExitProcess prevents it from executing. - }
- Constructor
- Constructor
- Constructor
- Constructor
- Destructor
- Destructor
调用TerminateProcess函数
TerminateProcess也会导致进程中止:
- BOOL
TerminateProcess(HANDLE hProcess, UINT fuExitCode);
所有线程中止
当进程内的所有线程终止时,操作系统将销毁进程地址空间,进程的退出码将被设置为最后一个线程的退出码。
进程终止时发生了什么
当进程终止时,下面的动作会被触发:
- 进程内的所有线程将被终止
- 进程创建的所有的用户对象和GUI对象将被释放,其引用的所有内核对象引用计数减1
- 进程的退出码从STILL_ACTIVE变为ExitProcess或TerminateProcess函数的相应参数
- 进程的内核对象状态变成signaled(关于内核对象状态,可参阅第9章)
- 进程的内核对象引用计数减1
注意进程内核对象的生命周期和进程的生命周期并不完全相同,进程终止只是将其内核对象的引用计数减1,如果此时另外的进程仍持有该对象的句柄,那么进程内核对象并不会销毁。这通常发生在父进程忘记关闭子进程的句柄时,这是一个特性,而不是BUG。进程内核对象维护着进程的统计信息,这些信息在进程终止之后依然是可用的。比如,你可以获得进程占用的CPU时间总数,或者用GetExitCodeProcess获得其退出码:
- BOOL
GetExitCodeProcess(HANDLE hProcess, PDWORD pdwExitCode);
再说一遍,当你对进程的统计信息不再感兴趣时,要记得调用CloseHandle关闭内核对象句柄,否则进程内核对象会一直存在。
- Windows viaC/C++:终止进程
- Windows via C/C++:终止进程
- 强行终止windows进程
- windows 内置终止进程命令
- ctrl+c不能终止进程
- windows进程信息查看 终止指定进程
- Windows程序设计——终止进程运行
- 终止指定的进程 windows程序设计,王艳平
- windows mobile终止一个指定的进程
- Windows NTSTATUS Values 进程终止消息标识符
- busybox ctrl+c不能终止进程(引用)
- 使用C语言查看/创建/终止进程
- Windows查看进程CMD命令和终止进程CMD命令
- Windows内核之进程的终止和子进程
- Windows查看进程CMD命令和终止进程CMD命令
- 终止进程
- 终止进程
- 终止进程
- 生成AWR报告
- 如何实现ajax延时发送
- Fragment 和 FragmentActivity的使用
- android 检查service是否停止
- CloudStack 配置高级网络简明手册
- Windows viaC/C++:终止进程
- MFC CWinApp派生类中使用CFrameWnd派生类的成员函数Create来创建窗口
- MFC中 窗口类位置结构体的使用CRET
- C++类的数据成员的初始化相关问题
- MFC 窗口风格WS-Window—Styles
- warning C4627
- 如何做好一个程序员--编程的思想--…
- CWnd与HWND的区别与转换
- MFC获得桌面的坐标完成在中间位置创建窗口