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 ...
随机推荐
- .Neter玩转Linux系列之四:Linux下shell介绍以及TCP、IP基础
基础篇 .Neter玩转Linux系列之一:初识Linux .Neter玩转Linux系列之二:Linux下的文件目录及文件目录的权限 .Neter玩转Linux系列之三:Linux下的分区讲解 .N ...
- BZOJ 2844: albus就是要第一个出场 [高斯消元XOR 线性基]
2844: albus就是要第一个出场 题意:给定一个n个数的集合S和一个数x,求x在S的$2^n$个子集从小到大的异或和序列中最早出现的位置 一开始看错题了...人家要求的是x第一次出现位置不是第x ...
- SpringMVC之HelloWorld实例
1.1 Helloworld实例的操作步骤 1. 加入jar包 2. 配置dispatcherServlet 3. 加入Spring配置文件 4. 编写请求处理器 并表示为处理器 5. 编写视图 1 ...
- qt中的多线程
1.dialog.h #define DIALOG_H #include <QDialog>#include"mythread.h"namespace Ui {clas ...
- cloud9 ide
https://github.com/tekacs/cloud9 http://www.pjhome.net/article/Javascript/nodeJS_IDE_cloud9.html htt ...
- Windows使用问题总结
1 电脑休眠恢复之后无法识别Wifi无线网络 首先,重启电脑:其次,打开网络和共享中心,点击更改适配器设置:最后,在对应的无线网络连接图标上点击鼠标右键,属性,配置,电源选项,允许计算机关闭此设备以节 ...
- angularjs 控制器、作用域、广播详解
一.控制器 首先列出几种我们平常使用控制器时的几种误区: 我们知道angualrJs中一个控制器时可以对应不同的视图模板的,但这种实现方式存在的问题是: 如果视图1和视图2根本没有任何逻辑关系,这样& ...
- SpringBoot中过滤器、监听器以及拦截器
属于javax.servlet所提供的Api 拦截器原理 简单来讲是通过动态代理实现,被访问的目标方法通过代理类(方法)来执行,这样我们就可以在真正要执行的方法执行前.后做一些处理: 通过拦截器这种方 ...
- wss 协议传送过来的数据是经过 gzip 压缩过的,如何使用 qt 解压该数据呢?
#include <QtZlib/zlib.h> QByteArray qGzipUncompress(const QByteArray& data) { if (!data.da ...
- 历届试题 大臣的旅费 树形DP
题目链接:大臣的旅费 思路:锦囊说用广搜,可惜这题没说数据范围,担心复杂度太高,我就直接用的树形DP--求树的最远路径. 以城市1为整棵树的根结点,d(i)表示以i为根结点的子树的最远路径,还有一个f ...