Tan*_*ury 475
Boost.Asio是一个C++库,首先关注网络,但其异步I/O功能已经扩展到其他资源.此外,Boost.Asio是Boost库的一部分,其范围略有缩小,以防止与其他Boost库重复.例如,Boost.Asio不会提供线程抽象,因为Boost.Thread已经提供了一个.
另一方面,libuv是一个C库,旨在成为Node.js的平台层.它为Windows 上的IOCP,macOS 上的kqueue和Linux上的epoll提供了抽象.此外,看起来它的范围略有增加,包括抽象和功能,如线程,线程池和线程间通信.
每个库的核心是提供事件循环和异步I/O功能.它们与某些基本功能重叠,例如定时器,套接字和异步操作.libuv具有更广泛的范围,并提供额外的功能,如线程和同步抽象,同步和异步文件系统操作,进程管理等.相比之下,Boost.Asio的原始网络焦点表面,因为它提供了更丰富的网络相关集功能,例如ICMP,SSL,同步阻塞和非阻塞操作,以及常见任务的更高级别操作,包括从流中读取直到收到换行符.
以下是一些主要功能的简要并列比较.由于使用Boost.Asio的开发人员通常可以使用其他Boost库,因此我选择考虑使用其他Boost库,如果它们是直接提供的,或者是实现的那么简单.
libuv Boost
Event Loop: yes Asio
Threadpool: yes Asio + Threads
Threading:
Threads: yes Threads
Synchronization: yes Threads
File System Operations:
Synchronous: yes FileSystem
Asynchronous: yes Asio + Filesystem
Timers: yes Asio
Scatter/Gather I/O[1]: no Asio
Networking:
ICMP: no Asio
DNS Resolution: async-only Asio
SSL: no Asio
TCP: async-only Asio
UDP: async-only Asio
Signal:
Handling: yes Asio
Sending: yes no
IPC:
UNIX Domain Sockets: yes Asio
Windows Named Pipe: yes Asio
Process Management:
Detaching: yes Process
I/O Pipe: yes Process
Spawning: yes Process
System Queries:
CPU: yes no
Network Interface: yes no
Serial Ports: no yes
TTY: yes no
Shared Library Loading: yes Extension[2]
1. 分散/聚集I/O.
2. Boost.Extension从未提交给Boost进行审核.如前所述这里,笔者认为它是完整的.
虽然libuv和Boost.Asio都提供了事件循环,但两者之间存在一些细微差别:
uv_default_loop())时需要注意,而不是创建新的循环(uv_loop_new()),因为另一个组件可能正在运行默认循环.io_service都是他们自己的循环,允许多个线程运行.为了支持这个Boost.Asio以一些性能为代价执行内部锁定.Boost.Asio的修订历史表明,已经进行了一些性能改进以最小化锁定.uv_queue_work.线程池大小可通过环境变量进行配置UV_THREADPOOL_SIZE.该工作将在事件循环之外和线程池内执行.工作完成后,完成处理程序将排队等待在事件循环中运行.io_service由于io_service允许多个线程调用,因此可以很容易地作为一个线程池运行run.这将线程管理和行为的责任交给用户,如本例所示.EAGAIN或EWOULDBLOCK.kill和信号处理.uv_signal_tuv_signal_*kill,但它signal_set提供信号处理.uv_pipe_t.local::stream_protocol::socket或local::datagram_protocol::socket,和windows::stream_handle.虽然API仅根据语言而有所不同,但以下是一些主要差异:
在Boost.Asio中,操作和处理程序之间存在一对一的映射.例如,每个async_write操作都会调用一次WriteHandler.许多libuv操作和处理程序都是如此.但是,libuv uv_async_send支持多对一映射.多次uv_async_send调用可能导致uv_async_cb被调用一次.
在处理任务时,例如从流/ UDP读取,处理信号或等待定时器,Boost.Asio的异步调用链更加明确.使用libuv,创建观察者以指定对特定事件的兴趣.然后为观察者启动循环,其中提供回调.收到兴趣事件后,将调用回调.另一方面,Boost.Asio要求每次应用程序有兴趣处理事件时发出操作.
为了帮助说明这种差异,这里是一个带Boost.Asio的异步读循环,其中async_receive调用将多次发出:
void start()
{
socket.async_receive( buffer, handle_read ); ----.
} |
.----------------------------------------------'
| .---------------------------------------.
V V |
void handle_read( ... ) |
{ |
std::cout << "got data" << std::endl; |
socket.async_receive( buffer, handle_read ); --'
}
Run Code Online (Sandbox Code Playgroud)
以下是与libuv相同的示例,handle_read每次观察者观察到套接字有数据时都会调用它:
uv_read_start( socket, alloc_buffer, handle_read ); --.
|
.-------------------------------------------------'
|
V
void handle_read( ... )
{
fprintf( stdout, "got data\n" );
}
Run Code Online (Sandbox Code Playgroud)
由于Boost.Asio中的异步调用链和libuv中的观察者,内存分配通常在不同时间发生.对于观察者,libuv推迟分配,直到它收到需要内存处理的事件.分配是通过用户回调完成的,在libuv内部调用,并延迟应用程序的释放责任.另一方面,许多Boost.Asio操作要求在发出异步操作之前分配内存,例如bufferfor 的情况async_read.Boost.Asio确实提供null_buffers了可用于侦听事件,允许应用程序推迟内存分配直到需要内存,尽管这已被弃用.
这种内存分配差异也表现在bind->listen->accept循环内.使用libuv,uv_listen创建一个事件循环,当连接准备好被接受时,它将调用用户回调.这允许应用程序推迟客户端的分配,直到尝试连接.另一方面,Boost.Asio listen只改变了状态acceptor.该async_accept用于连接事件监听,并要求对方在被调用之前进行分配.
不幸的是,我没有任何具体的基准数字来比较libuv和Boost.Asio.但是,我观察到在实时和近实时应用程序中使用库的类似性能.如果需要硬数字,libuv的基准测试可以作为起点.
此外,虽然应该进行性能分析以识别实际瓶颈,但要注意内存分配.对于libuv,内存分配策略主要限于分配器回调.另一方面,Boost.Asio的API不允许分配器回调,而是将分配策略推送到应用程序.但是,Boost.Asio中的处理程序/回调可能会被复制,分配和释放.Boost.Asio允许应用程序提供自定义内存分配功能,以便为处理程序实现内存分配策略.
Asio的发展至少可以追溯到2004年的OCT-2004,经过为期20天的同行评审后,它在2006年3月22日的Boost 1.35被接受.它还作为TR2网络库提案的参考实现和API .Boost.Asio有相当数量的文档,尽管其用途因用户而异.
API也具有相当一致的感觉.此外,异步操作在操作名称中是显式的.例如,accept是同步阻塞并且async_accept是异步的.API为常见的I/O任务提供免费功能,例如,从流\r\n中读取直到读取.还注意隐藏一些网络特定的细节,例如ip::address_v4::any()表示"所有接口"的地址0.0.0.0.
最后,Boost 1.47+提供了处理程序跟踪,这可以证明在调试时很有用,以及C++ 11支持.
根据他们的github图,Node.js的开发可以追溯到至少FEB-2009,libuv的开发日期可以追溯到2011年3月.该uvbook是一个libuv引进一个伟大的地方.API文档在这里.
总的来说,API相当一致且易于使用.可能是混淆源的一个异常是uv_tcp_listen创建观察者循环.这比通常具有其他观察者不同uv_*_start和uv_*_stop对函数来控制所述观察者环的寿命.此外,一些uv_fs_*操作具有相当数量的参数(最多7个).在存在回调(最后一个参数)的情况下确定同步和异步行为时,可以减少同步行为的可见性.
最后,快速浏览libuv 提交历史记录表明开发人员非常活跃.
Ole*_*rov 45
好.我有使用这两个库的经验,可以清除一些东西.
首先,从概念的角度来看,这些库的设计完全不同.它们具有不同的架构,因为它们具有不同的规模.Boost.Asio是一个大型网络库,旨在与TCP/UDP/ICMP协议,POSIX,SSL等一起使用.Libuv只是Node.js 的IOCP跨平台抽象层,主要是.所以libuv在功能上是Boost.Asio的子集(常见功能只有TCP/UDP套接字线程,定时器).就是这样,我们可以使用几个标准来比较这些库:
与新的C++特性集成:Asio更好(Asio 1.51广泛使用C++ 11异步模型,移动语义,可变参数模板).在成熟度方面,Asio是一个更稳定,更成熟的项目,具有良好的文档(如果将其与libuv进行比较)标题描述),互联网上的大量信息(视频讲座,博客:http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio? pg = 1,等等甚至书籍(不是专业人士,但仍然是:http://en.highscore.de/cpp/boost/index.html).Libuv只有一本在线书籍(但也很好)http://nikhilm.github.com/uvbook/index.html和几个视频会谈,所以很难知道所有的秘密(这个库有很多).有关函数的更具体讨论,请参阅下面的评论.
作为结论,我应该说这完全取决于你的目的,你的项目以及你打算做什么.
Vin*_*lco 16
一个巨大的区别是Asio(Christopher Kohlhoff)的作者正在修饰他的图书馆以包含在C++标准库中,参见http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175 .pdf和http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
| 归档时间: |
|
| 查看次数: |
52215 次 |
| 最近记录: |