boost asio allocation
allocation演示了自定义异步操作的内存分配策略,因为asio在执行异步IO操作时会使用系统函数来动态分配内存,使用完后便立即释放掉;在IO操作密集的应用中,这种内存动态分配策略会较大地影响程序的整体性能。为了避免这个问题,可以在在应用程序中创建一个内存块供asio异步IO操作使用,异步IO操作通过自定义接口 asio_handler_allocate 和 asio_handler_deallocate 来使用该内存块。该例子中使用到了 boost::aligned_storage<1024> storage_ 来管理原始内存。
cpp03
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// #include <cstdlib>
#include <iostream>
#include <boost/aligned_storage.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp> using boost::asio::ip::tcp; // Class to manage the memory to be used for handler-based custom allocation.
// It contains a single block of memory which may be returned for allocation
// requests. If the memory is in use when an allocation request is made, the
// allocator delegates allocation to the global heap.
class handler_allocator
: private boost::noncopyable
{
public:
handler_allocator()
: in_use_(false)
{
} void* allocate(std::size_t size)
{
if (!in_use_ && size < storage_.size)
{
in_use_ = true;
return storage_.address();
}
else
{
return ::operator new(size);
}
} void deallocate(void* pointer)
{
if (pointer == storage_.address())
{
in_use_ = false;
}
else
{
::operator delete(pointer);
}
} private:
// Storage space used for handler-based custom memory allocation.
boost::aligned_storage<> storage_; // Whether the handler-based custom allocation storage has been used.
bool in_use_;
}; // Wrapper class template for handler objects to allow handler memory
// allocation to be customised. Calls to operator() are forwarded to the
// encapsulated handler.
template <typename Handler>
class custom_alloc_handler
{
public:
custom_alloc_handler(handler_allocator& a, Handler h)
: allocator_(a),
handler_(h)
{
} template <typename Arg1>
void operator()(Arg1 arg1)
{
handler_(arg1);
} template <typename Arg1, typename Arg2>
void operator()(Arg1 arg1, Arg2 arg2)
{
handler_(arg1, arg2);
} friend void* asio_handler_allocate(std::size_t size,
custom_alloc_handler<Handler>* this_handler)
{
return this_handler->allocator_.allocate(size);
} friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
custom_alloc_handler<Handler>* this_handler)
{
this_handler->allocator_.deallocate(pointer);
}
private:
handler_allocator& allocator_;
Handler handler_;
};
// Helper function to wrap a handler object to add custom allocation.
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator& a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
} class session
: public boost::enable_shared_from_this<session>
{
public:
session(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
socket_.async_read_some(boost::asio::buffer(data_),
make_custom_alloc_handler(allocator_,
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
boost::asio::async_write(socket_,
boost::asio::buffer(data_, bytes_transferred),
make_custom_alloc_handler(allocator_,
boost::bind(&session::handle_write,
shared_from_this(),
boost::asio::placeholders::error)));
}
}
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(data_),
make_custom_alloc_handler(allocator_,
boost::bind(&session::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
}
private:
// The socket used to communicate with the client.
tcp::socket socket_;
// Buffer used to store data received from the client.
boost::array<char, > data_;
// The allocator to use for handler-based custom memory allocation.
handler_allocator allocator_;
}; typedef boost::shared_ptr<session> session_ptr;
class server
{
public:
server(boost::asio::io_service& io_service, short port)
: io_service_(io_service),
acceptor_(io_service, tcp::endpoint(tcp::v4(), port))
{
session_ptr new_session(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
void handle_accept(session_ptr new_session,
const boost::system::error_code& error)
{
if (!error)
{
new_session->start();
} new_session.reset(new session(io_service_));
acceptor_.async_accept(new_session->socket(),
boost::bind(&server::handle_accept, this, new_session,
boost::asio::placeholders::error));
}
private:
boost::asio::io_service& io_service_;
tcp::acceptor acceptor_;
}; int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
using namespace std; // For atoi.
server s(io_service, );
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
} return ;
}
cpp11
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// #include <array>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <type_traits>
#include <utility>
#include "asio.hpp" using asio::ip::tcp; // Class to manage the memory to be used for handler-based custom allocation.
// It contains a single block of memory which may be returned for allocation
// requests. If the memory is in use when an allocation request is made, the
// allocator delegates allocation to the global heap.
class handler_allocator
{
public:
handler_allocator()
: in_use_(false)
{
} handler_allocator(const handler_allocator&) = delete;
handler_allocator& operator=(const handler_allocator&) = delete; void* allocate(std::size_t size)
{
if (!in_use_ && size < sizeof(storage_))
{
in_use_ = true;
return &storage_;
}
else
{
return ::operator new(size);
}
} void deallocate(void* pointer)
{
if (pointer == &storage_)
{
in_use_ = false;
}
else
{
::operator delete(pointer);
}
} private:
// Storage space used for handler-based custom memory allocation.
typename std::aligned_storage<>::type storage_; // Whether the handler-based custom allocation storage has been used.
bool in_use_;
}; // Wrapper class template for handler objects to allow handler memory
// allocation to be customised. Calls to operator() are forwarded to the
// encapsulated handler.
template <typename Handler>
class custom_alloc_handler
{
public:
custom_alloc_handler(handler_allocator& a, Handler h)
: allocator_(a),
handler_(h)
{
} template <typename ...Args>
void operator()(Args&&... args)
{
handler_(std::forward<Args>(args)...);
} friend void* asio_handler_allocate(std::size_t size,
custom_alloc_handler<Handler>* this_handler)
{
return this_handler->allocator_.allocate(size);
} friend void asio_handler_deallocate(void* pointer, std::size_t /*size*/,
custom_alloc_handler<Handler>* this_handler)
{
this_handler->allocator_.deallocate(pointer);
} private:
handler_allocator& allocator_;
Handler handler_;
}; // Helper function to wrap a handler object to add custom allocation.
template <typename Handler>
inline custom_alloc_handler<Handler> make_custom_alloc_handler(
handler_allocator& a, Handler h)
{
return custom_alloc_handler<Handler>(a, h);
} class session
: public std::enable_shared_from_this<session>
{
public:
session(tcp::socket socket)
: socket_(std::move(socket))
{
} void start()
{
do_read();
} private:
void do_read()
{
auto self(shared_from_this());
socket_.async_read_some(asio::buffer(data_),
make_custom_alloc_handler(allocator_,
[this, self](std::error_code ec, std::size_t length)
{
if (!ec)
{
do_write(length);
}
}));
} void do_write(std::size_t length)
{
auto self(shared_from_this());
asio::async_write(socket_, asio::buffer(data_, length),
make_custom_alloc_handler(allocator_,
[this, self](std::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
do_read();
}
}));
} // The socket used to communicate with the client.
tcp::socket socket_; // Buffer used to store data received from the client.
std::array<char, > data_; // The allocator to use for handler-based custom memory allocation.
handler_allocator allocator_;
}; class server
{
public:
server(asio::io_service& io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
socket_(io_service)
{
do_accept();
} private:
void do_accept()
{
acceptor_.async_accept(socket_,
[this](std::error_code ec)
{
if (!ec)
{
std::make_shared<session>(std::move(socket_))->start();
} do_accept();
});
} tcp::acceptor acceptor_;
tcp::socket socket_;
}; int main(int argc, char* argv[])
{
try
{
if (argc != )
{
std::cerr << "Usage: server <port>\n";
return ;
} asio::io_service io_service;
server s(io_service, std::atoi(argv[]));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
} return ;
}
boost asio allocation的更多相关文章
- BOOST.Asio——Overview
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- boost::asio译文
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENS ...
- Boost.Asio技术文档
Christopher Kohlhoff Copyright © 2003-2012 Christopher M. Kohlhoff 以Boost1.0的软件授权进行发布(见附带的LICENSE_1_ ...
- BOOST ASIO 学习专贴
本文已于20170903更新完毕,所有boost asio 代码均为本人手抄.编译器为vs2013,并且所有代码已经上传,本文下方可下载源码 为了学习boost asio库,我是从boost的官方bo ...
- boost asio one client one thread
总结了一个简单的boost asio的tcp服务器端与客户端通信流程.模型是一个client对应一个线程.先做一个记录,后续再对此进行优化. 环境:VS2017 + Boost 1.67 serve ...
- c++ boost asio库初学习
前些日子研究了一个c++的一个socket库,留下范例代码给以后自己参考. 同步server: // asio_server.cpp : コンソール アプリケーションのエントリ ポイントを定義します. ...
- 如何在多线程leader-follower模式下正确的使用boost::asio。
#include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...
- BOOST.Asio——Tutorial
=================================版权声明================================= 版权声明:原创文章 谢绝转载 啥说的,鄙视那些无视版权随 ...
- boost asio sync
Service: #include<boost/asio.hpp> #include<boost/thread.hpp> #include<iostream> #i ...
随机推荐
- python 3.x 爬虫基础---Urllib详解
python 3.x 爬虫基础 python 3.x 爬虫基础---http headers详解 python 3.x 爬虫基础---Urllib详解 前言 爬虫也了解了一段时间了希望在半个月的时间内 ...
- redis新手入门,摸不着头脑可以看看<二>
对<Redis开发与运维>的理解--下文中引号部分来自该书,略有修改 P19. Redis有序集合(图2-1) "Redis有序集合和集合一样也是某种类型元素的集合,不重复.不 ...
- 03-PHP-memcached
[安装memcached] [安装 libevent] $ tar zxvf libevent-2.0.20-stable.tar.gz $ cd libevent-2.0.20-stable/ $ ...
- PHPUnit简介及使用
一.PHPUnit是什么? 1.它是一款轻量级的PHP测试框架,地址:http://www.phpunit.cn 2.手册:http://www.phpunit.cn/manual/5.7/zh_cn ...
- 【收藏】8段JQuery处理表单的代码片段,很实用
1 只接受数字输入 $("#uAge").keydown(function(event) { // 允许退格和删除键 if ( event.keyCode == 46 || eve ...
- curl模拟post和get请求
function _post($url,$post_data){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); ...
- 【剑指offer28:字符串的排列】【java】
题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. import ja ...
- 解决react-router4在browserhistory路由下的nginx的白屏或者404问题
使用react-router,官方推荐用browserhistory,美观简洁.但是nginx服务器端的配置也让人头疼. 首先看官方举例的方法: server { location / { try_f ...
- 箱型图boxplot函数的使用
主要参数: medlwd:设置中位线宽度 whiskcol:设置虚线颜色 staplecol:设置顶端颜色 outcol:离群值颜色 相应的具体位置: outline=FALSE:去除离群值 outp ...
- java并发 - 自底向上的原理分析
[TOC] 事先声明,我只是java并发的新手,这篇文章也只是我阅读<java并发编程的艺术>一书(内容主要涉及前3章)的一些总结和感悟.希望大家能多多讨论,对于错误的地方还请指出. 0. ...