进程能通信——智能指针

本文主要内容

  • 进程通信概念
  • 智能指针概念
  • 强指针
  • 弱指针

进程通信概念

同一个程序中两个函数能互相调用的根本原因是处于相同的内存空间中

因为是在同一个内存空间当中,虚拟地址的映射规则完全一致,所以不同函数间能找到另一函数的内存地址,所以可以调用到。

反之不同进程间,它们是没有办法直接调用另一进程的方法或者变量的。

Binder,粘合剂,它是android中使用最广泛的IPC机制。如果将Binder和TCP网络类比,会发现他们很相似:

  • Binder驱动器 —— 路由器
  • Service Manager ——DNS
  • Binder Client —— 客户端
  • Binder Server —— 服务器

智能指针概念

c/c++指针常常会有以下问题:

  • 指针没有初始化
  • new了对象后没有及时delete
  • 野指针,如果指针ptr指向对象obj,obj已经被delete了,但唯一没做的是将ptr置空,此时ptr就是野指针,如果在其它地方使用ptr,程序肯定会发生异常

针对以上三个问题,智能指针出现了。

第1个问题很好解决,只要在智能指针出现的时候置null即可。

为了解决第2个问题,我们使用引用计数法,计算当前对象被引用的次数,如果引用次数大于0,则不删除,反之则删除。

计数器由object自身管理,不能由智能指针管理,因为智能指针不能处理自己之外的引用。

object中实现增加计数和减少计数的方法,当智能指针引用此object时候增加计数,不再引用时则减少计数。

如上图所示,重载等号,在使用行号赋值的时候调用object的增加计数方法,在析构函数中,调用减少计数的方法。

如果有两个智能指针同时引用一个object,就会出现下图所示:

强指针SP

强指针sp,是StrongPointer的缩写,来看看它的代码:

它和前一小节的SmartPointer稍微有所不同,比如等号重载。

如果此前 m_ptr 不为空,则说明此智能指针正在引用其它object,此时则要将之前的object减少计数。

而其它构造函数和析构函数则与SmartPointer类似。强指针比较简单,不再赘述。

弱指针

引用计数法,有一个问题,就是循环引用问题,如果有两个对象互相引用,而且没有任何其它对象引用二者,那么这两对对象的计数器不为0,则永远不会被删除。

弱指针的主要使命就是解决循环引用问题,另外弱指针只有升级为强指针,才能访问它所指向的目标。


和sp相比,wp在定义上有以下区别:

  • 除了指向目标的m_ptr之外,wp另外还有一个m-refs指针,类型为 weakref_type
  • 没有重载 -> ,* 等运行符
  • 有一个prmote方法将弱指针升级为强指针
  • 目标对象的父类不是 LightRefBase,而我 RefBase

智能指针的套路,大致就是指针在引用的时候或者在析构的时候调用object的增加计数或者减少计数,那么弱指针会有什么不一样,查看其构造函数

在sp中,构造时会把计数器加1,但在wp中,调用createWeak方法,并且给m_refs赋值,并没有计数器,wp中m_refs充当计数器的功能。

这个函数属于前面提到的RefBase类,如下所示:

RefBase嵌套了一个重要的类weak_type,也就是前面的m_refs指针所属的类型,RefBase中也有一个weak_impl类型,从名称上看它是weakref_type的实现类。

weak_impl中有mWeak和mStrong,分别对应为弱引用计数器和强引用计数器,而且在构造的时候,把弱引用计数器赋值为0,强引用计数器赋值为另一个常量,因为理论上来说,弱引用计数器值大于强引用计数器。

到目前为止还没有看到createWeak,它定义在RefBase中,查看其实现:

createWeak先增加了mRefs的弱引用计数值,然后返回这个值。如果还有其它wp指向它,弱引用计数值继续增加

这个mRefs值被RefBase(object角色)和wp同时引用着,mRefs在RefBase构造时被创建,wp通过调用createWeak方法得到mRefs, 它们之间的关系如下:

弱指针看起来很复杂,但和强指针相比,只有一点不同,sp的计数器是int值,但wp的计数器是由weakref_impl管理。

如果有sp指向这个对象呢?

代码也比较简单,sp指向此对象时,需要增加弱引用计数值,也要增加强引用计数值。因为强引用计数值在初始化的时候被赋值为常量,如果是第一次,还需要加这个常量值,以保证强引用计数值从0开始。

接下来我们看对象什么时候会被释放:

当减少强引用计数的时候,先减少强引用计数值,如果强引用计数值已经为0,则删除对象自己,即RefBase,同时还要减少弱引用计数值,查看减少弱引用计数的方法:

此函数分成两个部分看,上述部分比较简单,只是减少弱引用计数即可。

这部分与weakref_impl的mFlags值有关,如果弱引用计数值为0,然后根据mFlags值,如果weakref_impl它的mStrong值是常量或者其它情况,分别删除 impl-mBase或者impl,这里就是释放weakref_impl的地方。

为什么不在RefBase被释放的时候释放weakref_impl呢?因为做不到,当强引用计数值为0的时候,弱引用计数器往往不为0,所以RefBase的析构函数无法生效。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容

  • 指针 在传统的C++编程中,指针的使用一直是一把双刃剑。指针赋予了我们直接操作硬件地址的能力,但同时也带来了诸多问...
    passerbywhu阅读 2,854评论 0 2
  • 前言 Java 和 C/C++ 的一个重大区别,就是它没有"指针"的概念,这并不代表 Java 不需要只用指针,而...
    seraphzxz阅读 2,479评论 0 54
  • Android跨进程通信IPC整体内容如下 1、Android跨进程通信IPC之1——Linux基础2、Andro...
    隔壁老李头阅读 4,777评论 2 5
  • Android 强弱指针分析 在C C++ 语言中,内存的管理历来是一个比较难的问题,在java 中内存n...
    赤兔欢阅读 1,930评论 0 2
  • 无论是轻量级指针还是强指针或弱指针,它们的实现原理都是类似的,即需要对象提供引用计数器(某公共类),但是由智能指针...
    魏国彬阅读 302评论 0 0