ACE的陷阱

所需积分/C币:9 2012-09-16 23:10:27 385KB PDF
0
收藏 收藏
举报

坦白说,使用这个标题无非是希望能够吸引你的眼球,这篇文章的目的仅仅是为了揭示一些ACE 缺陷的。文章适合的读者是对ACE(ADAPTIVE Communication Environment)有一定研究, 或者正在使用ACE从事项目开发的人士参考。如果你对C++还是新手,甚至包括ACE知识初学者,(但 你想飞的更高),建议你收藏这篇文档以后阅读。 秉承陷阱系列文章的传统,我只是通过一些辩证的角度去看ACE的一些不足,对于ACE的强大 和优美我就不再作赞美。从2000年,到现在,ACE在中国已经从星星之火,开始有燎原之势。这一 方面说明ACE的优美和实力已经逐步得到大家的认可(我所知道的Adob
的陷阱 作者:雁渡寒潭 的陷阱 坦白说,使用这个标题无非是希望能够吸引你的眼球这篇文章的目的仅仅是为了揭示一些 缺陷的。文章适合的读者是对 )有定研究, 或者正在使用从事项目廾发的人上参考。如果你对还是新手,甚至包括知识初学者,(但 你想飞的更高),建议你收癜这篇文档以后阅读。 秉承陷阱系列文章的传统,我只是通过一些辩证的角度去看的一些不足,对于的强大 和优关我就不雨作赞关。从年,到现在,在中国己经从星星之火,开始有燎原之势。这 方面说明的优美和实力已经逐步得到人家的认可(我所知道的 的使用,估 计是为了跨平台,内的大量电信的网管,计费,智能网软件也使用),一方面要感谢的是的 马维达这位国内少有的职业作家,国内的的中文资料(包括大量兔费资料)都出自这位老兄。 但无疑是复杂的,能够畅快的遨游在其中的绝对不是泛泛之辈。没有对网终,设计模式, 操作系统有·定的底缊,想痛快的驾驭无疑是较难的。另外,由于仍然处在逐步发展的过 程中。他的很多问题仍然有待进一步完善。重要的是一些文案的不足,受众面狭小,导致许多 的使用者在使用的时候会碰上很多问题。这篇文案就是用」彻底揭示部分这些问题。希望大家 能在更加顺捷的使用它。 另外,请注意我使用的陷阱这个术语,而不是原罪。( 倒有很多应 该是 )还在不停的发展中。很多问题可能会在以后的版本中间改进。所以在我 认为的的确是问题的章节后面,我会附上知道错误的版本号。 我将什么列为陷阱 低效的模块 作为一个代码级的中间件。无疑是高效的,但是坦白说的代码不是非常完美的。 的很多地方提供的是一个框架解决方案,为了保证框架的可移植和通用,代码中大量使用了 响数, 模式,多线程下的锁操作,甚至有相当的操作……,这些东西都限制 的性能。所以个人谨慎的将的效率定义为中上。 个人认为,一般情况下,如果你使用的代替系统,速度应该降低以下,主要 导致这些差役在于的再次封装,而函数栈的调用成本应该可以几乎不计。的优势在高性能 的系统架构,而不是绝对的函数性能,如果你要再考虑在加入系统框架的其它功能呢,(举一个例 第页共页 的陷阱 作者:雁渡寒潭 子,当你想把定时器优关的合入你的代码时),就有足够的优势让你选择但。【注】 在此啰嗦一句,同样也有很多人质疑的性能.所有奷的类库一样,他带来优势的同时也会有一定的遗憾 比如少量性能降低。但是如果说他们的性能不好,那是无稽之谈。(不信,把你认为性能差的代码给我写写看 建议固步自封的程序员不要再千买椟还珠的事情,先云读读那些优美的代码。 但是和所有的框架样,也有不少的地方的地方是性能的暗憔,你最好绕开。当然般而 言会提供多条道路,重要的是你能选择正确。 设计缺陷 的有多个层次,侧记缺陷这类错误往往出现在的高阶封装中。同时由于是一个跨平 台的中间件。所以为了平台的兼容性,做了很多折中和弥补,有些是很漂亮的,但有些却不是 非常理想。 使用不便的地方 所有的代码都是不完的,特别是这种要让无数人在无数环境下使用的软件。很多使用不 便的问题都是来自我个人的一些习惯,这些算是苛责了。 容易误解或者误用的地方 由于的庞大性,很多时候大家会错误的理解使用的某些代码实现某些特性。在此将写 些曾经让我们栽跟头的阴沟写出来。另方面,的文档的某些介绍也存在含混,会误导大家 的理解,错误的地方 的链接错误 很多人在 使用的时候往往会出现以下的错误 其实这个错误不是由」导致的,只是编译器把这个赃栽倒了上。出现这个错淏的原因 主要是因为一些关键宏定义冲突,一般是 个函数是 后才出现的函数,如果这个宏被定义的小于 或者没有定义,那么就会出现 这个错误。 所以最简单的处玛方法是在自己的预定义头文件中加入 第页共页 的陷阱 作者:雁渡寒潭 其实自己对于宏的处理是比较严谨的,的 中间就有这行定 义,所以在一般而言,可以将的头文件包含定义放在在顶部,这样也可以避免这个编译错误。 预定义头文件是一个良好的编程习惯,你可以将自u的大部分宏定义, 包含的木工程 以夕的外部文件。简言之就是定义头文件中使用 ,表小包含工程以外文件,自己 工程内部只使用 ,表示包含当前工程日录下的文件。大部分的程序员都有过链 接和一些预定义冲突错误消耗人量的时间,原来我也是如此,但是在掌握预定义头文件方法后,我 几乎没有为这个问题折席过。其实 在生产工程的时候,会自动帮你自动生产 个预定义头文件 ,只是我们不善利用而已。 其实对于很多编译器,使用预定义头文件还可以加快编译速度 的预定义会生产一个文件,基 本可以提高编译速度一倍。 的工程中间有专门的预定义头文件设置。 采用可以采用的编译宏 (好像是专用的)加快编译逴度。大致的原理是编译器会在对预定义头文件中包含的文件进行与处理,在外部文件 没有发生改动的时候,编译器可以伕用编译这些文件生成的中间文件加快编译速度。 不要使用 有一个非常优美的定时器队列模型,他提供了种定时器 让大家使用 。在《 中间有相应的说明,其中按照说明最诱人的的是 但是遗憾的是, 其实是性能最差的。几乎不值得使用。我曾经也被诱惑过, 但是在沨试中间发现,文档中所述根本不属实,在一个大规模定时器的程序中,我使用 发现性能非常不理想,检查后发现的源代码如下 为的桶尺小,如果要避免冲突,桶的数量应该尽量人, 每个桶可以理解为一个开链的链表 遍历所有的桶 在每个桶中检查是否有要进行超时处理的元素 第页共页 的陷阱 作者:雁渡寒潭 简单说明一下上面的代码, 采用开链的方式,每个桶就是一个链表 在超时检查时所有的桶中是由有要进行超时处理的元素。所以在超时处理中采用了遍历所有元 素的方法。但悖论是如果你希望的冲突不大,你就必须将桶的个数调整的尽量多。我在测试中 将上述的程序的 替换为标准的的 ,发现性能提髙数百倍。 冷静下来思考下,这也是止常的。对于个的实现,保证查询的速度,也就是通过定吋 器进行操作的速度是足够快的。但是实际上对于定时器操作,最大的成本应该是寻找要超时的定 时器,对」这种数据结构,只能采用迭代遍历的方式……,所以采用的低效是正常的。 而原文应该改为 的最好时间复杂度是,最差是 而 的时间 复杂度始终是 这个问题在自己的文档《 》中间也有较为正确的描述 这个问题至少倒的版木还是存在的。我个人估计也不会得到解决。 的特性摆在那儿 呢,除非采用更加复杂的数据结构 定时器的精度取决于实现 由于 在各个平台的默认实现都取决于平台的实现,比如在 下默认的 是 ,而在 和平台,默认的 是 而 的实现往往取决于使用的反应器底层实现,而这些反应器的时间精度就决定了你的定时器 的时间精度。下表大致反馈了一些常用的定时器的实现。 表常用 的实现 反应器的底层实现 时间精度 函数 使用 结构进行超时处 理 结构可以精确倒微秒。 或者而 参数的单位是毫秒。 的参数单位是毫秒 不过作为服务器的开发,我倒想不岀什么地方需要精确到定吋付器的地方,了解下差异性 就足够了。 第页共页 的陷阱 作者:雁渡寒潭 的与众不同 在 下的默认实现(为什么不选择 作为默认实现,可能是基于效率和强大性的考虑) 层使用的函数是 和 其中 函数用于处理线程,互斥量,信号灯,事件,定时器等事件,而 用于处理网络事件。 由于 和操作系统的特性不一样, 在很多地方的表现和其他平台 不一致。【注】 【注】其实这两个问题在《 》中 有说明。这儿算是借花献佛 只能处理个句柄 由于 不是一个处大量事件的函数,其最多处理个事件句枘, 而 自身为了处理使用了个句柄,所以一个 对象只能处理。 如果你想做大规模的网络接入,个事件句柄显然是不够的,特别是要同时处理事件时,导 致这个不足的应该是 的设计者的一个选择。在赋予 强人的特性的同 的设计者只能让网络事件的数量委屈一下了 触发机制 选择的是 的 函数作为网络的的反应器。但是 数的 的事件处理和传统的反应器( )不同。下面是 的措述。 简单翻译就是,只有在三种条件下, 才会发出 通知,一是使用 或 ,一个套接字成功建立连接后;二是使用 或 ,套接字 被接受以后;三是若 或 函数返回失败,而且错误是 错误后,缓冲区的空间再次变得可用时。【注】 第页共页 的陷阱 作者:雁渡寒潭 【注】这种触发方式在反应器或者说多路复用模型中应该被称为边缘触发方式 函数好象没有这种 触发方式而是水平触发方式, 是支持这种方式的,但是默认还是水平触发,这种方式可能有更高的效率,但 是代码更加难写。 可以这么理解 认为套接字基本都是可写状态,它认为你应该大胆 只有出现 失败后,你才需要使用 反应器。【注】 所以对于 的,你不可能依靠注册(或者是唤酲)句柄进行写操作, 很有可能不会去回调你的 函数 【注】对于冈络套捩字,只要缓冲区还有空间就可以直接发送,除非缓冲区没有空间了,才可能岀现阻蹇错淏, 所以直接失败的可能性很小,另外反复调用注册句柄一类的操作其实是比较耗时的。其实,如果 失败再注册勹勺柄到反应器的方式应该是一种更加高效的方式:高压力的選讯服务器应该选择这个编写方式。 我自己的通信服务器通过这个改造,提高的性能在左右(占用率下降)。 由于 的这些特点,其实很大的限制了 的可移植性。其实个人感觉如果 你对系统特性没有那么多要求,在 下选择 替換 是更好 的选择。 尽量使用取消 定时器 的 提供了两种方式取消定吋器: 种是使用定时器取消定时器,这个是定时器是的返回值,一种是采用相应的 指针取消定时器。一股情况下使用 的指针取消定时器 无疑是最简单的方法,但是这个方法却不是个高效的实现。所以如果您的程序有大规模的定时器 设置取消操作,建议尽量使用取消定时器。我们用 和 两个 剖析一下 如何根据 取消 先选择最常用的 举例,其使用 关闭定 时器的代码是: 第页共页 的陷阱 作者:雁渡寒潭 循环比较所有的的 的指针是否相同 而使用 关闭的代码如下,它是通过数组下标进行的定位操作。 通过数组下标操作,速度当然奇快无比。 跟进数组进行操作 对于 ,采用 指针取消定时器的方式的平均时间复杂 度应该就是。由于的的个 可能对应多个定时器,所以必须检查所有的 才能确保取消所有的相关定吋器。 如何根据 取消 对于 ,其通过 关闭定时器的代码是: 根据 有一个定时器个数组出来 根据定时器的个数再进行取消 可以看到 比 )要好 点点。但是其中也有和 操作,这些操作也不是髙效操作。 所以说在大规模的定时器使用中,推荐你还是使用定吋器的取消定吋器更加扃效的多 第页共页 的陷阱 作者:雁渡寒潭 注意 的实现 是一个跨平台的管道实现。标准情况来讲,采用的实现,但是在最大的两个平 和 上 的实现是采用的 实现。 绑定了一个本地端凵, ,然后找到相应的端凵,用于后面的链接 所以很多管道特性所特有的东西,在这两个平台上是无法使用 实现的。比如,管道 的特性可以保证在暂时没有接受者的情况下使用,而 是不可能有这个特性的。你必须保证 先有接受者,后有发送者的时序。 所以在这些平台上最好不用这个封装。 慎用 机制 在 的模式,有一种辅助的通知机制 机制,简单说就是通过通知发起者调用 函数 的消息被保存在一个管道中 的处理中会检查这个管道中是 否有通知数据,如果有就根据通知的消息,会根据默认的通知消息的类型去调用 等 函数。 从设计的角度将,这个机制无疑是非常优美的,对于 它在驱动以外,提供了一种 新的驱动方式。但是从实现角度来讲,这个机制要慎用。原因有两个。 的默认方式采用的是 的默认 方式采用的是 ,所以 在 和 平台上的问题, 机制把 的缺陷一个不少的继承了,而且问题更加多。 第页共页

...展开详情
试读 30P ACE的陷阱
立即下载 低至0.43元/次 身份认证VIP会员低至7折
一个资源只可评论一次,评论内容不能少于5个字
  • 分享王者

    成功上传51个资源即可获取
关注 私信 TA的资源
上传资源赚积分or赚钱
    最新推荐
    ACE的陷阱 9积分/C币 立即下载
    1/30
    ACE的陷阱第1页
    ACE的陷阱第2页
    ACE的陷阱第3页
    ACE的陷阱第4页
    ACE的陷阱第5页
    ACE的陷阱第6页

    试读结束, 可继续读3页

    9积分/C币 立即下载 >