Chinaunix首页 | 论坛 | 博客
  • 博客访问: 87044
  • 博文数量: 11
  • 博客积分: 1536
  • 博客等级: 上尉
  • 技术积分: 160
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-26 22:01
文章分类

全部博文(11)

文章存档

2011年(4)

2010年(2)

2009年(3)

2008年(2)

我的朋友

分类: C/C++

2011-01-12 16:45:03

    asio中大量使用handler, 几乎所有的异步函数都带有handler参数. 在调用这些函数时, asio会分配一片内存保存这个handler, 以便在异步完成时调用这个handler. 而这些handler大小往往很小, 因为里面只有几个参数.
    以下代码来自boost_1_45/libs/asio/example/allocation/server.cpp
    首先需要实现一个类模板custom_alloc_handler, 该类模板允许handler对象使用自定义的内存分配器. custom_alloc_handler需要实现operator(), asio_handler_allocate 和 asio_handler_deallocate 模板函数.
  1. template <typename Handler>
  2. class custom_alloc_handler
  3. {
  4. public:
  5.   custom_alloc_handler(handler_allocator& a, Handler h): allocator_(a), handler_(h)
  6.   {
  7.   }

  8.   template <typename Arg1>
  9.   void operator()(Arg1 arg1) 
  10.   {
  11.     handler_(arg1);
  12.   }

  13.   template <typename Arg1, typename Arg2>
  14.   void operator()(Arg1 arg1, Arg2 arg2) 
  15.   {
  16.     handler_(arg1, arg2);
  17.   }

  18.   friend void* asio_handler_allocate(std::size_t size,
  19.       custom_alloc_handler<Handler>* this_handler)
  20.   {
  21.     return this_handler->allocator_.allocate(size);
  22.   }

  23.   friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
  24.       custom_alloc_handler<Handler>* this_handler)
  25.   {
  26.     this_handler->allocator_.deallocate(pointer);
  27.   }

  28. private:
  29.   handler_allocator& allocator_;     // 自定义的内存分配器
  30.   Handler handler_;
  31. };
然后实现一个模板函数
 template <typename Handler>
  1. inline custom_alloc_handler<Handler> make_custom_alloc_handler(
  2.     handler_allocator& a, Handler h)
  3. {
  4.   return custom_alloc_handler<Handler>(a, h);
  5. }
这样, 在调用asio中异步函数的时候, 大多数情况下就是输入boost::bind()的地方, 修改为
  1. make_custom_alloc_handler(allocator_, boost::bind(...));

后话:

其实实现这段代码的必要性并不是很大, 反复调用的时候诚然会有很多小块的内存, 但是实际应用中, stl的list, map, vector 等以及相关迭代器的应用同样会带来一样的问题, 如果每次都这样定义std:list list; 我想你肯定会头痛, 何况内存池很可能是后期为了优化才加进去的.
因此在此建议项目前期直接new/delete就行了, 等到系统稳定, 可以考虑使用google的内存池的解决方案 google-perftools:


阅读(2651) | 评论(0) | 转发(1) |
0

上一篇:boost asio 简单示例

下一篇:C++中的SFINAE

给主人留下些什么吧!~~