对C 资源管理内容分析研究
创始人
2024-06-22 05:40:50
0

下面进行对C++资源管理的问题进行讲解,那么首先要对C++语言的概念进行了解,所谓C++语言:它是一种使用非常广泛的计算机编程语言,C++已经成为当今主流程序设计语言中最复杂的一员。

首先简要的介绍一下 RAII 。这个思想的基本手法是对于一种想要使用的资源,为其书写一个 guard 类,在该类的构造函数里进行资源的请求,在析构函数里进行资源的释放。例如假设我们想管理一个互斥锁,可能的方式是:

  1. struct  lock_guard  
  2.   {          
  3.     lock_guard() { lock ();}   
  4.     ~ lock_guard() {unlock();}   
  5.    } ; 

此后,对这个对象使用什么内存管理方式,也就等价于对这个互斥锁使用什么内存管理方式。借助于 RAII ,以后我们可以只讨论内存资源的管理方式,其它资源的管理方式可以使用 RAII 来同样的实现。

现在我们已经很自然的获得了资源管理的 3 种方式:基于堆的动态方式、基于栈的自动方式和全局。值得一提的是,这 3 种方式中比较不容易出错的后两种实际上可以解决大部分的资源管理需求。

因为绝大部分资源,都属于获取 - 使用 - 释放型的,例如很多同步对象,文件锁, WinGDI 里的许多 GDI 对象。我们缺乏管理的,只有那些一次获得,多个环境拥有,并且只能有一次释放的少数资源。

回到内存模型来看,有一点让我们无法将内存与其它资源等同(反过来,把其它资源和内存等同却是可以的),那就是循环引用。

 A 内存可以持有指向 B 内存的引用, B 内存也可以反过来持有 A 内存的引用。循环引用导致内存管理不可以用“是否有指向该内存的引用”来区分一块内存是否可以回收。从而丧失了一个***的管理手段。但是在没有循环引用的场合下,我们还是有非常简洁高效的管理方法的。那就是引用计数。

引用计数是在没有循环引用场合下进行内存管理的***手段,它具有轻量、高效、即时、可控的优点。而且在C++资源管理里,引用计数已经非常成熟,只需要使用 boost.shared_ptr 或者其它非官方的引用计数指针库就可以了,而且据悉 C++资源管理很可能把 boost.shared_ptr 纳入标准库。

引用计数的原则是,如果一个对象没有别的指针或引用来指向它,那么这个对象就是可以释放的。引用计数通常可以处理哪些场合的资源管理问题呢?首先,对于单方向的资源管理,也就是多个 A 的实体拥有 1 个 B ,然而 B 并不会反过来依赖于 A (例如多个对象共享一个日志),引用计数是非常合适的。

其次,对于拥有反作用的场合,也就是 1 个或多个 A 的实体拥有 1 个或多个 B ,而 B 也拥有这些 A 的实体的引用,但是 B 的生存期仍然决定于 A 的生存期(例如父窗口拥有若干子窗口,子窗口也具有 parent 指针指向父窗口。

但是子窗口的生存期决定于父窗口的生存期),这个时候 A 可以对 B 使用引用计数指针,而 B 可以对 A 使用原生的普通指针,同样的可以很好的解决问题。 现在所剩下的,就只有生存期的循环依赖了。如果 AB 互相持有对方的引用,而且 AB 互相的存在都依赖于对方,这样引用计数就无法解决了。

但是如果仔细想一下就会发现,这种情况在C++资源管理里几乎不可能存在。生存期循环依赖只有 2 种后果,要么 A 和 B 的析构函数里互相析构(当然就挂了),要么互相都不析构(当然就泄露了)。#t#

而这两种都是在正常编程中不会出现的情况。所以如果即使仅仅使用引用计数,我们也可以解决几乎所有的资源管理问题。 现在回过头来看 Java/C# 这样的内置 gc 的语言。这样的语言由于使用了 gc ,就不可避免的放弃了析构函数。为什么 gc 会和析构函数产生冲突呢?

一个 gc 一般会希望在进行垃圾回收的时候,整个过程是一个原子的,但析构函数会破坏这一点,在释放内存的时候如果还要执行代码,那么难免会对整个 gc 环境产生破坏性的影响。

由于没有析构函数,这些语言就不可能做到 RAII ,也就是说,它们的C++资源管理所能够管理的,也就仅仅只有内存而已了。对于其他资源, Java 等就必须手动释放。虽然 C# 提供了 with 关键字来缓解这一问题,但仍然无法彻底的解决。

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...