我承认这个帖子的名称有标题党的嫌疑,但是暂时想不出更好的名称了,只好先这样了 :-(
由于前天的帖子聊了架构设计的多进程问题
,所以今天想起来要聊一下和“C++进程终止”相关的那些事。与前几个C++帖子的风格类似,今天聊的内容,尽量局限于标准C++范畴,尽量不涉及特定的操作系统平台。<!-- program-think-->
★关于进程的三种死法
由于今天讲的是“进程篇”,自然得先搞明白进程的几种死法。其实进程和大活人一样,也有三种死法,分别是“自然死亡、自杀、它杀”。这三种死亡方式具体如下:
1、自然死亡
望文生义,自然死亡就是最自然的进程退出方法。具体表现为通过return语句结束main函数。由于这种方法最优雅(后面会说),如果没有其它特殊原因,强烈建议采用这种死法。
2、自杀
所谓的自杀,就是进程自己调用某些API来自行了断。在标准C++中,这几个函数(exit、abort、terminate、unexpected)
可以用于进程自杀。如果没有额外设置,unexpected函数默认会调用terminate函数,terminate函数默认会调用abort函数。所
以自杀的方式基本上也就是exit和abort两种。exit相对abort来说温和一些,所以下文称exit为温和自杀
;相对地,把abort称为激进自杀
。
3、它杀
它杀其实也挺好理解,就是当前进程被其它进程杀死。标准C++没有提供用于它杀的API函数,因此常用的方法是通过某些跨平台的库(如ACE)提供的API函数或者调用某些外部命令(如Posix系统的kill命令)来实现。
上面说了这几种死法,有同学要问了:进程不同的死法和C++对象有什么关系捏?其实关系大大滴,请听我细细道来。
★类对象的析构(销毁)
首先把类对象分为三种:局部非静态对象、局部静态对象、非局部对象(出于习惯,以下简称全局对象
)。对于尚不清楚这几种对象差异的同学,请先找本C++入门书拜读一下。进程不同的死法对于这几种对象是否能销毁会有很大的影响。请看如下的对照表:
------------------------------
局部非静态对象 局部静态对象 全局对象
自然死亡 能 能 能
温和自杀 不能 能 能
激进自杀 不能 不能 不能
它杀 不能 不能 不能
------------------------------
从这个对照表可以看出,激进自杀和它杀的效果类似(各种
类对象都无法正常销毁)。所以我们在写程序时要极力避免上述这两种情况。
另外,温和自杀也有不爽之处:不能正确地销毁局部非静态对象。准确地说,应该是:在调用exit之前已经构造但是尚未析构的局部非静态
对象将再也不会被析构。所以温和自杀也要避免使用。
综上所述,最正经、最靠谱的死法就是第一种:自然死亡。
★析构的顺序
那么,是不是只要让进程自然死亡就万事大吉了?非也!即使所有的类对象都会被析构,还有另一个棘手的问题:析构的顺序。先来看下面一个例子:
class CFoo
{
public:
CFoo()
{
cout << "CFoo" << endl;
}
virtual ~CFoo()
{
cout << "~CFoo" << endl;
}
};
上述示例挺简单的(有效代码仅6行),大伙儿能看出有什么问题吗?如果你一眼就看出问题之所在,恭喜你,后面的内容你不用看了。
对于用户定义的全局对象,在C++标准中并没有规定它们构造和析构的先后顺序;对于诸如标准输入输出流的cout、cerr等全局对象,在C++
03标准中(参见27.4.2.1.6章节)有提及如何保证它们在最后析构。但由于某些老式编译器并未完全遵照标准实现,导致标准输入输出流的几个全局对
象也可能
被提前析构。
基于上述原因,假如CFoo类也定义了一个全局对象g_foo。当g_foo析构的时候,cout对象可能
已经先死了(取决于具体的环境,详见“关于标准输入输出流的进一步探讨
”)。在这种情况下,CFoo析构函数的打印语句由于引用了已死的对象,可能会
导致不可预料的后果。
从上面的例子可以看出,如果你在程序中使用了全局对象或者静态对象,那你要非常小心地编写相关class/struct的析构函数代码,尽量不要在它们的析构函数中引用其它的全局对象或静态对象。当然啦,假如能避免使用全局对象和静态对象,就更好了。
另外,在C++经典名著《Modern C++ Design》的第6章详细描述了关于单键(Singleton)销毁的一些细节、场景及解决方法。大伙儿可以去拜读一下。
下一个帖子,会聊一下和线程有关的C++对象是怎么死的
。
版权声明
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者编程随想
和本文原始地址:
http://program-think.blogspot.com/2009/02/cxx-object-destroy-with-process.html
分享到:
相关推荐
本篇文章将深入探讨如何使用C++通过WMI实现这一功能。 首先,我们需要理解WMI的基本概念。WMI是基于Microsoft的分布式管理任务组(DMTF)的Common Information Model (CIM)标准,它提供了一种统一的方式来获取和...
本篇将深入讲解C++中使用File Mapping进行进程间通信的示例。 共享内存是IPC方法之一,它通过让多个进程共享一块在内存中的特定区域来实现通信。相比于其他通信机制如管道、套接字或消息队列,共享内存具有更高的...
本篇将详细探讨如何使用Visual C++实现进程的创建,以及相关的编程技巧。 首先,我们需要了解Windows API中的`CreateProcess`函数,它是创建新进程的主要接口。`CreateProcess`函数接受一系列参数,包括要执行的可...
2.2 将C++对象移进DLL中——例程DB_cppdll 2.2.1 成员函数的引出 2.2.2 内存分配 2.2.3 Unicode/ASCII兼容 2.2.4 例程实现 2.2.4.1 修改接口文件 2.2.4.2 修改对象程序 2.2.4.3 修改客户程序 2.3 C++对象使用...
在IT领域,Visual C++是一种强大的编程环境,尤其在Windows平台下开发桌面应用程序时不可或缺。本文将深入探讨“Visual C++实践与提高——COM和COM+篇”中的关键概念和技术,帮助开发者提升对COM(Component Object ...
《Visual C++实践与提高_COM和COM+篇》是一本专注于使用Microsoft的Visual C++进行组件对象模型(COM)和组件对象模型加(COM+)技术开发的书籍。COM是微软提出的一种面向对象的技术,它允许不同语言编写的软件组件之间...
本篇文章将详细探讨如何在VB中监听进程的退出状态。 首先,我们要了解什么是进程句柄。在Windows操作系统中,每个进程都有一个唯一的标识符,即进程ID,以及一个句柄(Handle),句柄是操作系统用来管理和操作进程...
本篇文章将深入探讨"一个进程管理源码"中的关键知识点,以"ProcView"为例进行分析。 1. 进程管理基础: - **进程**:在操作系统中,进程是程序的执行实例,包含程序代码、数据、环境变量和一个执行上下文。每个...
这部分旨在帮助读者理解COM的核心概念,以及如何将传统C++对象转变为符合COM规范的对象。此外,它还讨论了COM的常见应用,例如自动化技术、ActiveX控件等,并讲述了如何在不同开发语言和环境中使用COM组件。 第二...
类工厂负责创建组件实例,代理和桩用于跨进程通信,引用计数则确保了对象生命周期的正确管理。 接着,书中详细阐述了如何使用Visual C++来开发COM组件,包括使用 ATL (Active Template Library) 进行高效COM编程。...
《Visual C++实践与提高:COM和COM+篇》是一本深入探讨Microsoft的组件对象模型(Component Object Model,简称COM)及其增强版COM+的专著。这本书旨在帮助读者掌握利用Visual C++进行COM和COM+开发的核心技术,并...
实训主题:Linux系统编程之文件篇、Linux系统编程之进程篇、Linux系统编程之信号篇、Linux系统编程之管道篇。 实战项目:Minishell。 阶段四:Linux网络编程 课程目标:掌握Linux网络编程基础知识,掌握socket编程...
#### 第2篇 Visual C++中对象的建模与表达 - **主题概述**:探讨了在Visual C++环境下如何有效地进行对象建模与表达,涉及基本数据类型到复杂对象结构的设计与实现。 - **主要内容**: - **常见对象的表达**: - ...
本综合技术篇将深入探讨C++中的多线程概念、实现方法以及常见问题。 一、线程基础 线程是操作系统分配处理器时间的基本单元,每个线程都有自己的程序计数器、寄存器和栈空间,共享同一进程的内存空间。在C++11及...
第四篇主要讲解Visual C++的开发,包括数据库编程、网络编程、线程同步与进程通信、动态链接库、ActiveX技术和Visual C++的调试技术。第五篇案例篇讲解了如何应用Visual C++进行实际综合案例开发。 本书重点分析了...
《Visual C++实践与提高-COM和COM篇》是一本专注于使用Microsoft的Visual C++进行组件对象模型(Component Object Model,简称COM)编程的专著。这本书深入浅出地介绍了COM技术及其在实际开发中的应用,是提升C++...
这本书详细介绍了C++语言的核心概念,从基本的语法结构到面向对象编程,再到STL(Standard Template Library,标准模板库)的使用。初学者可以从中学到如何声明和初始化变量,理解类和对象的概念,以及如何使用继承...
《2022校招面试题库(附答案与解析)C++篇》是一个针对C++编程语言的全面面试准备资源,旨在帮助应聘者在校园招聘面试中取得成功。这份资料涵盖了C++的基础知识,数据库原理,数据结构与算法,计算机网络,操作系统...
第四篇主要讲解Visual C++的开发,包括数据库编程、网络编程、线程同步与进程通信、动态链接库、ActiveX技术和Visual C++的调试技术。第五篇案例篇讲解了如何应用Visual C++进行实际综合案例开发。 本书重点分析了...