I'd be interested in aspects like:
我会对以下方面感兴趣:
- scope/features
- 范围/功能
- performance
- 性能
- maturity
- 成熟
3 个解决方案
#1
425
Scope
Boost.Asio is a C++ library that started with a focus on networking, but its asynchronous I/O capabilities have been extended to other resources. Additionally, with Boost.Asio being part of the Boost libraries, its scope is slightly narrowed to prevent duplication with other Boost libraries. For example, Boost.Asio will not provide a thread abstraction, as Boost.Thread already provides one.
提振。Asio是一个以网络为中心的c++库,但是它的异步I/O功能已经扩展到其他资源。此外,与提升。Asio作为Boost库的一部分,其范围略有缩小,以防止与其他Boost库的重复。例如,提振。Asio不会提供线程抽象作为Boost。线程已经提供了。
On the other hand, libuv is a C library designed to be the platform layer for node.js. It provides an abstraction to IOCP for Windows and libev on Unix systems. Although there are efforts to remove libev as noted in this issue. Additionally, it looks as though its scope has increased slightly to include abstractions and functionality, such as threads, threadpools, and inter-thread communication.
另一方面,libuv是一个C库,设计为node.js的平台层。它为Unix系统上的Windows和libev提供了IOCP的抽象。尽管在这个问题上有努力消除libev。此外,它的范围似乎有所增加,包括抽象和功能,如线程、线程池和线程间通信。
At their core, each library provides an event loop and asynchronous I/O capabilities. They have overlap for some of the basic features, such as timers, sockets, and asynchronous operations. libuv has a broader scope, and provides additional functionality, such as thread and synchronization abstractions, synchronous and asynchronous file system operations, process management, etc. In contrast, Boost.Asio's original networking focus surfaces, as it provides a richer set of network related capabilities, such as ICMP, SSL, synchronous blocking and non-blocking operations, and higher-level operations for common tasks, including reading from a stream until a newline is received.
在它们的核心,每个库都提供一个事件循环和异步I/O功能。它们对一些基本特性有重叠,如计时器、套接字和异步操作。libuv具有更广泛的范围,并提供了其他功能,如线程和同步抽象、同步和异步文件系统操作、流程管理等。Asio最初的网络焦点是表面的,因为它提供了一组更丰富的网络相关功能,如ICMP、SSL、同步阻塞和非阻塞操作,以及用于公共任务的高级操作,包括从流读取数据直到接收到换行。
Feature List
Here is the brief side-by-side comparison on some of the major features. Since developers using Boost.Asio often have other Boost libraries available, I have opted to consider additional Boost libraries if they are either directly provided or trivial to implement.
下面是一些主要特征的简单对比。因为开发人员使用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 was never submitted for review to Boost. As noted here, the author considers it to be complete.
2。提振。扩展从来没有提交给审查来推动。如前所述,作者认为它是完整的。
Event Loop
While both libuv and Boost.Asio provide event loops, there are some subtle differences between the two:
同时还有libuv和Boost。Asio提供事件循环,两者之间有一些微妙的区别:
- While libuv supports multiple event loops, it does not support running the same loop from multiple threads. For this reason, care needs to be taken when using the default loop (
uv_default_loop()
), rather than creating a new loop (uv_loop_new()
), as another component may be running the default loop. - 虽然libuv支持多个事件循环,但不支持从多个线程运行相同的循环。由于这个原因,在使用默认循环(uv_default_loop()))时需要注意,而不是创建一个新的循环(uv_loop_new()),因为另一个组件可能正在运行默认循环。
- Boost.Asio does not have the notion of a default loop; all
io_service
are their own loops that allow for multiple threads to run. To support this Boost.Asio performs internal locking at the cost of some performance. Boost.Asio's revision history indicates that there have been several performance improvements to minimize the locking. - 提振。Asio没有默认循环的概念;所有io_service都是它们自己的循环,允许多个线程运行。支持这种刺激。Asio以牺牲性能为代价实现内部锁定。提振。Asio的修订历史表明,有一些性能改进可以最小化锁定。
Threadpool
- libuv's provides a threadpool through
uv_queue_work
. The threadpool size is an implementation detail, and does not appear to be configurable through the API. The work will be executed outside of the event loop and within the threadpool. Once the work is completed, the completion handler will be queued to run within the event loop. - libuv通过uv_queue_work提供一个threadpool。threadpool大小是实现的详细信息,并且似乎不能通过API进行配置。该工作将在事件循环和threadpool之外执行。完成工作后,完成处理程序将排队在事件循环中运行。
- While Boost.Asio does not provide a threadpool, the
io_service
can easily function as one as a result ofio_service
allowing multiple threads to invokerun
. This places the responsibility of thread management and behavior to the user, as can be seen in this example. - 而提高。Asio不提供线程池,由于io_service允许多个线程调用运行,所以io_service可以轻松地作为一个线程运行。这将线程管理和行为的责任交给用户,如本例所示。
Threading and Synchronization
- libuv provides an abstraction to threads and synchronization types.
- libuv提供了对线程和同步类型的抽象。
-
Boost.Thread provides a thread and synchronization types. Many of these types follow closely to the C++11 standard, but also provide some extensions. As a result of Boost.Asio allowing multiple threads to run a single event loop, it provides
strands
as a means to create a sequential invocation of event handlers without using explicit locking mechanisms. - 提振。线程提供线程和同步类型。这些类型中的许多紧跟c++ 11标准,但也提供了一些扩展。作为推进的结果。Asio允许多个线程运行单个事件循环,它提供了链作为一种方法来创建事件处理程序的顺序调用,而无需使用显式锁定机制。
File System Operations
- libuv provides an abstraction to many file system operations. There is one function per operation, and each operation can either be synchronous blocking or asynchronous. If a callback is provided, then the operation will be executed asynchronously within an internal threadpool. If a callback is not provided, then the call will be synchronous blocking.
- libuv为许多文件系统操作提供了抽象。每个操作都有一个函数,每个操作可以是同步阻塞,也可以是异步的。如果提供回调,那么操作将在内部线程池中异步执行。如果没有提供回调,则调用将是同步阻塞。
- Boost.Filesystem provides synchronous blocking calls for many file system operations. These can be combined with Boost.Asio and a threadpool to create asynchronous file system operations.
- 提振。文件系统为许多文件系统操作提供同步阻塞调用。这些可以与Boost相结合。Asio和一个threadpool创建异步文件系统操作。
Networking
- libuv supports asynchronous operations on UDP and TCP sockets, as well as DNS resolution. Application developers should be aware that the underlying file descriptors are set to non-blocking. Therefore, native synchronous operations should check return values and errno for
EAGAIN
orEWOULDBLOCK
. - libuv支持UDP和TCP套接字的异步操作,以及DNS解析。应用程序开发人员应该知道底层文件描述符被设置为非阻塞。因此,本机同步操作应该检查EAGAIN或eif dblock的返回值和errno。
- Boost.Asio is a bit more rich in its networking support. In addition many of the features libuv's networking provides, Boost.Asio supporting SSL and ICMP sockets. Furthermore, Boost.Asio provides synchronous blocking and synchronous non-blocking operations, into addition to its asynchronous operations. There are numerous free standing functions that provide common higher-level operations, such as reading a set amount of bytes, or until a specified delimiter character is read.
- 提振。Asio在网络支持方面更为丰富。此外,libuv的网络提供了许多功能。Asio支持SSL和ICMP套接字。此外,提振。除了异步操作之外,Asio还提供同步阻塞和同步非阻塞操作。有许多免费的站函数,它们提供常见的高级操作,例如读取一组字节,或者直到读取指定的分隔符。
Signal
- libuv provides an abstraction
kill
and signal handling with itsuv_signal_t
type anduv_signal_*
operations. At the moment, only the default event loop supports signals. - libuv通过其uv_signal_t类型和uv_signal_*操作提供抽象kill和信号处理。目前,只有默认事件循环支持信号。
- Boost.Asio does not provde an abstraction to
kill
, but itssignal_set_service
provides signal handling. - 提振。Asio并不是为了杀死一个抽象,而是它的signal_set_service提供了信号处理。
IPC
- libuv abstracts Unix Domain Sockets and Windows Named Pipes through a single
uv_pipe_t
type. - libuv通过一个uv_pipe_t类型抽象Unix域套接字和Windows命名管道。
- Boost.Asio separates the two into local::stream_protocol::socket/local::datagram_protocol::socket and
windows::stream_handle
. - 提振。Asio将两者分成本地::stream_protocol::socket/local::datagram_protocol:::socket和windows::stream_handle。
API Differences
While the APIs are different based on the language alone, here are a few key differences:
虽然api是基于语言本身而不同的,但以下是一些关键的区别:
Operation and Handler Association
Within Boost.Asio, there is a one-to-one mapping between an operation and a handler. For instance, each async_write
operation will invoke the WriteHandler once. This is true for many of libuv operations and handlers. However, libuv's uv_async_send
supports a many-to-one mapping. Multiple uv_async_send
calls may result in the uv_async_cb being called once.
在提高。Asio,在操作和处理程序之间有一个一对一的映射。例如,每个async_write操作都会调用WriteHandler一次。这对许多libuv操作和处理程序都是如此。然而,libuv的uv_async_send支持多对一映射。多个uv_async_send调用可能导致uv_async_cb被调用一次。
Call Chains vs. Watcher Loops
When dealing with task, such as reading from a stream/UDP, handling signals, or waiting on timers, Boost.Asio's asynchronous call chains are a bit more explicit. With libuv, a watcher is created to designate interests in a particular event. A loop is then started for the watcher, where a callback is provided. Upon receiving the event of interests, the callback will be invoked. On the other hand, Boost.Asio requires an operation to be issued each time the application is interested in handling the event.
当处理任务时,例如从流/UDP中读取、处理信号或等待计时器时,Boost。Asio的异步调用链更显式一些。有了libuv,一个观察者就被创造出来去指定某一事件的兴趣。然后为监视者启动一个循环,其中提供一个回调。在接收到相关事件后,将调用回调。另一方面,是Boost。Asio需要在每次应用程序对处理事件感兴趣时发出操作。
To help illustrate this difference, here is an asynchronous read loop with Boost.Asio, where the async_receive
call will be issued multiple times:
为了说明这种差异,这里有一个带有Boost的异步读循环。Asio,异步接收调用将被多次发出:
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 ); --'
}
And here is the same example with libuv, where handle_read
is invoked each time the watcher observes that the socket has data:
这里是libuv的一个例子,每次当watcher观察到套接字有数据时,就会调用handle_read。
uv_read_start( socket, alloc_buffer, handle_read ); --.
|
.-------------------------------------------------'
|
V
void handle_read( ... )
{
fprintf( stdout, "got data\n" );
}
Memory Allocation
As a result of the asynchronous call chains in Boost.Asio and the watchers in libuv, memory allocation often occurs at different times. With watchers, libuv defers allocation until after it receives an event that requires memory to handle. The allocation is done through a user callback, invoked internal to libuv, and defers deallocation responsibility of the application. On the other hand, many of the Boost.Asio operations require that the memory be allocated before issuing the asynchronous operation, such as the case of the buffer
for async_read
. Boost.Asio does provide null_buffers
, that can be used to listen for an event, allowing applications to defer memory allocation until memory is needed.
由于Boost中的异步调用链。Asio和libuv的观察者经常在不同的时间进行内存分配。对于观察者,libuv会延迟分配,直到它收到一个需要内存处理的事件。分配通过用户回调完成,在libuv内部调用,并解除应用程序的释放位置责任。另一方面,许多刺激。Asio操作要求在发出异步操作之前分配内存,例如异步读取的缓冲区。提振。Asio确实提供了null_buffers,可以侦听事件,允许应用程序将内存分配延迟到需要内存时。
This memory allocation difference also presents itself within the bind->listen->accept
loop. With libuv, uv_listen
creates an event loop that will invoke the user callback when a connection is ready to be accepted. This allows the application to defer the allocation of the client until a connection is being attempted. On the other hand, Boost.Asio's listen
only changes the state of the acceptor
. The async_accept
listens for the connection event, and requires the peer to be allocated before being invoked.
这种内存分配差异也出现在bind->listen->接受循环中。使用libuv, uv_listen创建一个事件循环,当连接准备接受时,该循环将调用用户回调。这允许应用程序将客户机的分配延迟到尝试连接时。另一方面,是Boost。Asio的听觉只会改变接受者的状态。async_accept侦听连接事件,并要求在被调用之前分配对等点。
Performance
Unfortunately, I do not have any concrete benchmark numbers to compare libuv and Boost.Asio. However, I have observed similar performance using the libraries in real-time and near-real-time applications. If hard numbers are desired, libuv's benchmark test may serve as a starting point.
不幸的是,我没有任何具体的基准数据来比较libuv和Boost.Asio。但是,我观察到在实时和近实时应用程序中使用库也有类似的性能。如果需要硬数据,libuv的基准测试可以作为起点。
Additionally, while profiling should be done to identify actual bottlenecks, be aware of memory allocations. For libuv, the memory allocation strategy is primarily limited to the allocator callback. On the other hand, Boost.Asio's API does not allow for an allocator callback, and instead pushes the allocation strategy to the application. However, the handlers/callbacks in Boost.Asio may be copied, allocated, and deallocated. Boost.Asio allows for applications to provide custom memory allocation functions in order to implement a memory allocation strategy for handlers.
此外,当分析应该用于识别实际的瓶颈时,请注意内存分配。对于libuv,内存分配策略主要限于分配器回调。另一方面,是Boost。Asio的API不允许分配器回调,而是将分配策略推给应用程序。但是,Boost中的处理程序/回调。Asio可以被复制、分配和分配。提振。Asio允许应用程序提供自定义内存分配函数,以便为处理程序实现内存分配策略。
Maturity
Boost.Asio
Asio's development dates back to at least OCT-2004, and it was accepted into Boost 1.35 on 22-MAR-2006 after undergoing a 20-day peer review. It also served as the reference implementation and API for Networking Library Proposal for TR2. Boost.Asio has a fair amount of documentation, although its usefulness varies from user to user.
Asio的发展至少可以追溯到2004 -2004年,在经历了20天的同行评议后,它在22- 3 -2006年被接受为Boost 1.35。它还作为TR2网络库提案的参考实现和API。提振。Asio有相当数量的文档,尽管其用处因用户而异。
The API also have a fairly consistent feel. Additionally, the asynchronous operations are explicit in the operation's name. For example, accept
is synchronous blocking and async_accept
is asynchronous. The API provides free functions for common I/O task, for instance, reading from a stream until a \r\n
is read. Attention has also been given to hide some network specific details, such as the ip::address_v4::any()
representing the "all interfaces" address of 0.0.0.0
.
API也具有相当一致的感觉。此外,异步操作在操作名中是显式的。例如,accept是同步阻塞,async_accept是异步的。API为常见的I/O任务提供免费函数,例如,从流中读取数据,直到读取一个\r\n。还需要注意隐藏一些特定于网络的细节,如ip::address_v4: any()表示0.0.0.0.0.0.0的“所有接口”地址。
Finally, Boost 1.47+ provides handler tracking, which can prove to be useful when debugging, as well as C++11 support.
最后,Boost 1.47+提供了处理程序跟踪,这在调试时是很有用的,并且支持c++ 11。
libuv
Based on their github graphs, Node.js's development dates back to at least FEB-2009, and libuv's development dates to MAR-2011. The uvbook is a great place for a libuv introduction. The API is documented in the form of a detailed header, but could still use contributions in some areas.
基于他们的github图,Node。js的发展至少可以追溯到FEB-2009年,libuv的发展可以追溯到2011年3月。uvbook是libuv介绍的好地方。API以详细的头文件的形式记录,但是仍然可以在某些方面使用贡献。
Overall, the API is fairly consistent and easy to use. One anomaly that may be a source of confusion is that uv_tcp_listen
creates a watcher loop. This is different than other watchers that generally have a uv_*_start
and uv_*_stop
pair of functions to control the life of the watcher loop. Also, some of the uv_fs_*
operations have a decent amount of arguments (up to 7). With the synchronous and asynchronous behavior being determined on the presence of a callback (the last argument), the visibility of the synchronous behavior can be diminished.
总的来说,API是相当一致的,易于使用。一个可能引起混淆的异常是uv_tcp_listen创建一个监视循环。这与一般拥有uv_*_start和uv_*_stop函数对来控制监视循环生命的其他观察者不同。另外,一些uv_fs_*操作具有相当数量的参数(最多7个)。
Finally, a quick glance at the libuv commit history shows that the developers are very active.
最后,快速浏览一下libuv提交历史,就会发现开发人员非常活跃。
#2
45
Ok. I have some experience in using both libraries and can clearify some things.
好的。我在使用这两种库方面都有一定的经验,我还能清理一些东西。
First, from a conceptual view-point these libraries are quite different in design. They have different architectures, because they are of different scale. Boost.Asio is a large networking library aimed to be used with TCP/UDP/ICMP protocols, POSIX, SSL and so on. Libuv is just a layer for cross-platform abstraction of IOCP for Node.js, predominantly. So libuv is functionally a subset of Boost.Asio (common features only TCP/UDP Sockets threads,timers). Being that the case, we can compare these libraries using only few criteria:
首先,从概念的角度来看,这些库在设计上是完全不同的。他们有不同的架构,因为他们有不同的规模。提振。Asio是一个大型网络库,旨在与TCP/UDP/ICMP协议、POSIX、SSL等一起使用。Libuv只是一个用于节点IOCP的跨平台抽象层。js为主。所以libuv在功能上是Boost的一个子集。Asio(通用特性只有TCP/UDP套接字线程,定时器)。在这种情况下,我们可以用很少的标准来比较这些库:
- Integration with Node.js - Libuv is considerably better because it is aimed for this (we can fully integrate it and use in all aspects, for instance, cloud e.g. windows azure). But Asio also implements almost the same functionality as in Node.js event queue driven environment.
- 与节点的集成。js - Libuv更好,因为它是针对这个目的的(我们可以充分集成它并在所有方面使用,例如云,例如windows azure)。但Asio也实现了与Node几乎相同的功能。js事件队列驱动环境。
- IOCP Performance - I couldn't see great differencies, because both these libraries abstract underlying OS API. But they do it in a different way: Asio heavily uses C++ features such as templates and sometimes TMP. Libuv is a native C-library. But nevertheless Asio realisation of IOCP is very efficient. UDP sockets in Asio are not good enough it is better to use libuv for them.
Integration with new C++ features: Asio is better (Asio 1.51 extensively use C++11 asynchronous model, move semantics, variadic templates).In regard to maturity, Asio is a more stable and mature project with good documentation (if compare it to libuv headers description), a lot of information across the Internet (video talks, blogs: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=1 ,etc.) and even books (not for professionals but nevertheless: http://en.highscore.de/cpp/boost/index.html ). Libuv has only one online book (but also good) http://nikhilm.github.com/uvbook/index.html and several video talks, so it will be difficult to know all the secrets (this library has a lot of them). For more specific discussion of functions see my comments below.
集成新的c++特性:Asio更好(Asio 1.51广泛使用c++异步模型、移动语义、可变模板)。就成熟度而言,Asio是一个更稳定、更成熟的项目,拥有良好的文档(如果与libuv header描述相比),它包含了互联网上的大量信息(视频对话,博客:http://www.gamedev.net/blog/950/entry-2249317-a-guide- get -started- boostasio?pg=1,等等),甚至书籍(不是为专业人士准备的,但是:http://en.highscore.de/cpp/boost/index.html)。Libuv只有一本在线图书(但也不错)http://nikhilm.github.com/uvbook/index.html和几个视频讲座,所以很难知道所有的秘密(这个图书馆有很多)。有关函数的更具体讨论,请参阅下面我的评论。
As conclusion, I should said that it all depends on your purposes, your project and what concretely you intend to do.
最后,我想说,这一切都取决于你的目的、你的项目以及你打算具体做什么。
#3
13
One huge difference is the author of Asio (Christopher Kohlhoff) is grooming his library for inclusion in the C++ Standard Library, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175.pdf and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
一个巨大的不同是,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/papers/papers/paper4370.html
#1
425
Scope
Boost.Asio is a C++ library that started with a focus on networking, but its asynchronous I/O capabilities have been extended to other resources. Additionally, with Boost.Asio being part of the Boost libraries, its scope is slightly narrowed to prevent duplication with other Boost libraries. For example, Boost.Asio will not provide a thread abstraction, as Boost.Thread already provides one.
提振。Asio是一个以网络为中心的c++库,但是它的异步I/O功能已经扩展到其他资源。此外,与提升。Asio作为Boost库的一部分,其范围略有缩小,以防止与其他Boost库的重复。例如,提振。Asio不会提供线程抽象作为Boost。线程已经提供了。
On the other hand, libuv is a C library designed to be the platform layer for node.js. It provides an abstraction to IOCP for Windows and libev on Unix systems. Although there are efforts to remove libev as noted in this issue. Additionally, it looks as though its scope has increased slightly to include abstractions and functionality, such as threads, threadpools, and inter-thread communication.
另一方面,libuv是一个C库,设计为node.js的平台层。它为Unix系统上的Windows和libev提供了IOCP的抽象。尽管在这个问题上有努力消除libev。此外,它的范围似乎有所增加,包括抽象和功能,如线程、线程池和线程间通信。
At their core, each library provides an event loop and asynchronous I/O capabilities. They have overlap for some of the basic features, such as timers, sockets, and asynchronous operations. libuv has a broader scope, and provides additional functionality, such as thread and synchronization abstractions, synchronous and asynchronous file system operations, process management, etc. In contrast, Boost.Asio's original networking focus surfaces, as it provides a richer set of network related capabilities, such as ICMP, SSL, synchronous blocking and non-blocking operations, and higher-level operations for common tasks, including reading from a stream until a newline is received.
在它们的核心,每个库都提供一个事件循环和异步I/O功能。它们对一些基本特性有重叠,如计时器、套接字和异步操作。libuv具有更广泛的范围,并提供了其他功能,如线程和同步抽象、同步和异步文件系统操作、流程管理等。Asio最初的网络焦点是表面的,因为它提供了一组更丰富的网络相关功能,如ICMP、SSL、同步阻塞和非阻塞操作,以及用于公共任务的高级操作,包括从流读取数据直到接收到换行。
Feature List
Here is the brief side-by-side comparison on some of the major features. Since developers using Boost.Asio often have other Boost libraries available, I have opted to consider additional Boost libraries if they are either directly provided or trivial to implement.
下面是一些主要特征的简单对比。因为开发人员使用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 was never submitted for review to Boost. As noted here, the author considers it to be complete.
2。提振。扩展从来没有提交给审查来推动。如前所述,作者认为它是完整的。
Event Loop
While both libuv and Boost.Asio provide event loops, there are some subtle differences between the two:
同时还有libuv和Boost。Asio提供事件循环,两者之间有一些微妙的区别:
- While libuv supports multiple event loops, it does not support running the same loop from multiple threads. For this reason, care needs to be taken when using the default loop (
uv_default_loop()
), rather than creating a new loop (uv_loop_new()
), as another component may be running the default loop. - 虽然libuv支持多个事件循环,但不支持从多个线程运行相同的循环。由于这个原因,在使用默认循环(uv_default_loop()))时需要注意,而不是创建一个新的循环(uv_loop_new()),因为另一个组件可能正在运行默认循环。
- Boost.Asio does not have the notion of a default loop; all
io_service
are their own loops that allow for multiple threads to run. To support this Boost.Asio performs internal locking at the cost of some performance. Boost.Asio's revision history indicates that there have been several performance improvements to minimize the locking. - 提振。Asio没有默认循环的概念;所有io_service都是它们自己的循环,允许多个线程运行。支持这种刺激。Asio以牺牲性能为代价实现内部锁定。提振。Asio的修订历史表明,有一些性能改进可以最小化锁定。
Threadpool
- libuv's provides a threadpool through
uv_queue_work
. The threadpool size is an implementation detail, and does not appear to be configurable through the API. The work will be executed outside of the event loop and within the threadpool. Once the work is completed, the completion handler will be queued to run within the event loop. - libuv通过uv_queue_work提供一个threadpool。threadpool大小是实现的详细信息,并且似乎不能通过API进行配置。该工作将在事件循环和threadpool之外执行。完成工作后,完成处理程序将排队在事件循环中运行。
- While Boost.Asio does not provide a threadpool, the
io_service
can easily function as one as a result ofio_service
allowing multiple threads to invokerun
. This places the responsibility of thread management and behavior to the user, as can be seen in this example. - 而提高。Asio不提供线程池,由于io_service允许多个线程调用运行,所以io_service可以轻松地作为一个线程运行。这将线程管理和行为的责任交给用户,如本例所示。
Threading and Synchronization
- libuv provides an abstraction to threads and synchronization types.
- libuv提供了对线程和同步类型的抽象。
-
Boost.Thread provides a thread and synchronization types. Many of these types follow closely to the C++11 standard, but also provide some extensions. As a result of Boost.Asio allowing multiple threads to run a single event loop, it provides
strands
as a means to create a sequential invocation of event handlers without using explicit locking mechanisms. - 提振。线程提供线程和同步类型。这些类型中的许多紧跟c++ 11标准,但也提供了一些扩展。作为推进的结果。Asio允许多个线程运行单个事件循环,它提供了链作为一种方法来创建事件处理程序的顺序调用,而无需使用显式锁定机制。
File System Operations
- libuv provides an abstraction to many file system operations. There is one function per operation, and each operation can either be synchronous blocking or asynchronous. If a callback is provided, then the operation will be executed asynchronously within an internal threadpool. If a callback is not provided, then the call will be synchronous blocking.
- libuv为许多文件系统操作提供了抽象。每个操作都有一个函数,每个操作可以是同步阻塞,也可以是异步的。如果提供回调,那么操作将在内部线程池中异步执行。如果没有提供回调,则调用将是同步阻塞。
- Boost.Filesystem provides synchronous blocking calls for many file system operations. These can be combined with Boost.Asio and a threadpool to create asynchronous file system operations.
- 提振。文件系统为许多文件系统操作提供同步阻塞调用。这些可以与Boost相结合。Asio和一个threadpool创建异步文件系统操作。
Networking
- libuv supports asynchronous operations on UDP and TCP sockets, as well as DNS resolution. Application developers should be aware that the underlying file descriptors are set to non-blocking. Therefore, native synchronous operations should check return values and errno for
EAGAIN
orEWOULDBLOCK
. - libuv支持UDP和TCP套接字的异步操作,以及DNS解析。应用程序开发人员应该知道底层文件描述符被设置为非阻塞。因此,本机同步操作应该检查EAGAIN或eif dblock的返回值和errno。
- Boost.Asio is a bit more rich in its networking support. In addition many of the features libuv's networking provides, Boost.Asio supporting SSL and ICMP sockets. Furthermore, Boost.Asio provides synchronous blocking and synchronous non-blocking operations, into addition to its asynchronous operations. There are numerous free standing functions that provide common higher-level operations, such as reading a set amount of bytes, or until a specified delimiter character is read.
- 提振。Asio在网络支持方面更为丰富。此外,libuv的网络提供了许多功能。Asio支持SSL和ICMP套接字。此外,提振。除了异步操作之外,Asio还提供同步阻塞和同步非阻塞操作。有许多免费的站函数,它们提供常见的高级操作,例如读取一组字节,或者直到读取指定的分隔符。
Signal
- libuv provides an abstraction
kill
and signal handling with itsuv_signal_t
type anduv_signal_*
operations. At the moment, only the default event loop supports signals. - libuv通过其uv_signal_t类型和uv_signal_*操作提供抽象kill和信号处理。目前,只有默认事件循环支持信号。
- Boost.Asio does not provde an abstraction to
kill
, but itssignal_set_service
provides signal handling. - 提振。Asio并不是为了杀死一个抽象,而是它的signal_set_service提供了信号处理。
IPC
- libuv abstracts Unix Domain Sockets and Windows Named Pipes through a single
uv_pipe_t
type. - libuv通过一个uv_pipe_t类型抽象Unix域套接字和Windows命名管道。
- Boost.Asio separates the two into local::stream_protocol::socket/local::datagram_protocol::socket and
windows::stream_handle
. - 提振。Asio将两者分成本地::stream_protocol::socket/local::datagram_protocol:::socket和windows::stream_handle。
API Differences
While the APIs are different based on the language alone, here are a few key differences:
虽然api是基于语言本身而不同的,但以下是一些关键的区别:
Operation and Handler Association
Within Boost.Asio, there is a one-to-one mapping between an operation and a handler. For instance, each async_write
operation will invoke the WriteHandler once. This is true for many of libuv operations and handlers. However, libuv's uv_async_send
supports a many-to-one mapping. Multiple uv_async_send
calls may result in the uv_async_cb being called once.
在提高。Asio,在操作和处理程序之间有一个一对一的映射。例如,每个async_write操作都会调用WriteHandler一次。这对许多libuv操作和处理程序都是如此。然而,libuv的uv_async_send支持多对一映射。多个uv_async_send调用可能导致uv_async_cb被调用一次。
Call Chains vs. Watcher Loops
When dealing with task, such as reading from a stream/UDP, handling signals, or waiting on timers, Boost.Asio's asynchronous call chains are a bit more explicit. With libuv, a watcher is created to designate interests in a particular event. A loop is then started for the watcher, where a callback is provided. Upon receiving the event of interests, the callback will be invoked. On the other hand, Boost.Asio requires an operation to be issued each time the application is interested in handling the event.
当处理任务时,例如从流/UDP中读取、处理信号或等待计时器时,Boost。Asio的异步调用链更显式一些。有了libuv,一个观察者就被创造出来去指定某一事件的兴趣。然后为监视者启动一个循环,其中提供一个回调。在接收到相关事件后,将调用回调。另一方面,是Boost。Asio需要在每次应用程序对处理事件感兴趣时发出操作。
To help illustrate this difference, here is an asynchronous read loop with Boost.Asio, where the async_receive
call will be issued multiple times:
为了说明这种差异,这里有一个带有Boost的异步读循环。Asio,异步接收调用将被多次发出:
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 ); --'
}
And here is the same example with libuv, where handle_read
is invoked each time the watcher observes that the socket has data:
这里是libuv的一个例子,每次当watcher观察到套接字有数据时,就会调用handle_read。
uv_read_start( socket, alloc_buffer, handle_read ); --.
|
.-------------------------------------------------'
|
V
void handle_read( ... )
{
fprintf( stdout, "got data\n" );
}
Memory Allocation
As a result of the asynchronous call chains in Boost.Asio and the watchers in libuv, memory allocation often occurs at different times. With watchers, libuv defers allocation until after it receives an event that requires memory to handle. The allocation is done through a user callback, invoked internal to libuv, and defers deallocation responsibility of the application. On the other hand, many of the Boost.Asio operations require that the memory be allocated before issuing the asynchronous operation, such as the case of the buffer
for async_read
. Boost.Asio does provide null_buffers
, that can be used to listen for an event, allowing applications to defer memory allocation until memory is needed.
由于Boost中的异步调用链。Asio和libuv的观察者经常在不同的时间进行内存分配。对于观察者,libuv会延迟分配,直到它收到一个需要内存处理的事件。分配通过用户回调完成,在libuv内部调用,并解除应用程序的释放位置责任。另一方面,许多刺激。Asio操作要求在发出异步操作之前分配内存,例如异步读取的缓冲区。提振。Asio确实提供了null_buffers,可以侦听事件,允许应用程序将内存分配延迟到需要内存时。
This memory allocation difference also presents itself within the bind->listen->accept
loop. With libuv, uv_listen
creates an event loop that will invoke the user callback when a connection is ready to be accepted. This allows the application to defer the allocation of the client until a connection is being attempted. On the other hand, Boost.Asio's listen
only changes the state of the acceptor
. The async_accept
listens for the connection event, and requires the peer to be allocated before being invoked.
这种内存分配差异也出现在bind->listen->接受循环中。使用libuv, uv_listen创建一个事件循环,当连接准备接受时,该循环将调用用户回调。这允许应用程序将客户机的分配延迟到尝试连接时。另一方面,是Boost。Asio的听觉只会改变接受者的状态。async_accept侦听连接事件,并要求在被调用之前分配对等点。
Performance
Unfortunately, I do not have any concrete benchmark numbers to compare libuv and Boost.Asio. However, I have observed similar performance using the libraries in real-time and near-real-time applications. If hard numbers are desired, libuv's benchmark test may serve as a starting point.
不幸的是,我没有任何具体的基准数据来比较libuv和Boost.Asio。但是,我观察到在实时和近实时应用程序中使用库也有类似的性能。如果需要硬数据,libuv的基准测试可以作为起点。
Additionally, while profiling should be done to identify actual bottlenecks, be aware of memory allocations. For libuv, the memory allocation strategy is primarily limited to the allocator callback. On the other hand, Boost.Asio's API does not allow for an allocator callback, and instead pushes the allocation strategy to the application. However, the handlers/callbacks in Boost.Asio may be copied, allocated, and deallocated. Boost.Asio allows for applications to provide custom memory allocation functions in order to implement a memory allocation strategy for handlers.
此外,当分析应该用于识别实际的瓶颈时,请注意内存分配。对于libuv,内存分配策略主要限于分配器回调。另一方面,是Boost。Asio的API不允许分配器回调,而是将分配策略推给应用程序。但是,Boost中的处理程序/回调。Asio可以被复制、分配和分配。提振。Asio允许应用程序提供自定义内存分配函数,以便为处理程序实现内存分配策略。
Maturity
Boost.Asio
Asio's development dates back to at least OCT-2004, and it was accepted into Boost 1.35 on 22-MAR-2006 after undergoing a 20-day peer review. It also served as the reference implementation and API for Networking Library Proposal for TR2. Boost.Asio has a fair amount of documentation, although its usefulness varies from user to user.
Asio的发展至少可以追溯到2004 -2004年,在经历了20天的同行评议后,它在22- 3 -2006年被接受为Boost 1.35。它还作为TR2网络库提案的参考实现和API。提振。Asio有相当数量的文档,尽管其用处因用户而异。
The API also have a fairly consistent feel. Additionally, the asynchronous operations are explicit in the operation's name. For example, accept
is synchronous blocking and async_accept
is asynchronous. The API provides free functions for common I/O task, for instance, reading from a stream until a \r\n
is read. Attention has also been given to hide some network specific details, such as the ip::address_v4::any()
representing the "all interfaces" address of 0.0.0.0
.
API也具有相当一致的感觉。此外,异步操作在操作名中是显式的。例如,accept是同步阻塞,async_accept是异步的。API为常见的I/O任务提供免费函数,例如,从流中读取数据,直到读取一个\r\n。还需要注意隐藏一些特定于网络的细节,如ip::address_v4: any()表示0.0.0.0.0.0.0的“所有接口”地址。
Finally, Boost 1.47+ provides handler tracking, which can prove to be useful when debugging, as well as C++11 support.
最后,Boost 1.47+提供了处理程序跟踪,这在调试时是很有用的,并且支持c++ 11。
libuv
Based on their github graphs, Node.js's development dates back to at least FEB-2009, and libuv's development dates to MAR-2011. The uvbook is a great place for a libuv introduction. The API is documented in the form of a detailed header, but could still use contributions in some areas.
基于他们的github图,Node。js的发展至少可以追溯到FEB-2009年,libuv的发展可以追溯到2011年3月。uvbook是libuv介绍的好地方。API以详细的头文件的形式记录,但是仍然可以在某些方面使用贡献。
Overall, the API is fairly consistent and easy to use. One anomaly that may be a source of confusion is that uv_tcp_listen
creates a watcher loop. This is different than other watchers that generally have a uv_*_start
and uv_*_stop
pair of functions to control the life of the watcher loop. Also, some of the uv_fs_*
operations have a decent amount of arguments (up to 7). With the synchronous and asynchronous behavior being determined on the presence of a callback (the last argument), the visibility of the synchronous behavior can be diminished.
总的来说,API是相当一致的,易于使用。一个可能引起混淆的异常是uv_tcp_listen创建一个监视循环。这与一般拥有uv_*_start和uv_*_stop函数对来控制监视循环生命的其他观察者不同。另外,一些uv_fs_*操作具有相当数量的参数(最多7个)。
Finally, a quick glance at the libuv commit history shows that the developers are very active.
最后,快速浏览一下libuv提交历史,就会发现开发人员非常活跃。
#2
45
Ok. I have some experience in using both libraries and can clearify some things.
好的。我在使用这两种库方面都有一定的经验,我还能清理一些东西。
First, from a conceptual view-point these libraries are quite different in design. They have different architectures, because they are of different scale. Boost.Asio is a large networking library aimed to be used with TCP/UDP/ICMP protocols, POSIX, SSL and so on. Libuv is just a layer for cross-platform abstraction of IOCP for Node.js, predominantly. So libuv is functionally a subset of Boost.Asio (common features only TCP/UDP Sockets threads,timers). Being that the case, we can compare these libraries using only few criteria:
首先,从概念的角度来看,这些库在设计上是完全不同的。他们有不同的架构,因为他们有不同的规模。提振。Asio是一个大型网络库,旨在与TCP/UDP/ICMP协议、POSIX、SSL等一起使用。Libuv只是一个用于节点IOCP的跨平台抽象层。js为主。所以libuv在功能上是Boost的一个子集。Asio(通用特性只有TCP/UDP套接字线程,定时器)。在这种情况下,我们可以用很少的标准来比较这些库:
- Integration with Node.js - Libuv is considerably better because it is aimed for this (we can fully integrate it and use in all aspects, for instance, cloud e.g. windows azure). But Asio also implements almost the same functionality as in Node.js event queue driven environment.
- 与节点的集成。js - Libuv更好,因为它是针对这个目的的(我们可以充分集成它并在所有方面使用,例如云,例如windows azure)。但Asio也实现了与Node几乎相同的功能。js事件队列驱动环境。
- IOCP Performance - I couldn't see great differencies, because both these libraries abstract underlying OS API. But they do it in a different way: Asio heavily uses C++ features such as templates and sometimes TMP. Libuv is a native C-library. But nevertheless Asio realisation of IOCP is very efficient. UDP sockets in Asio are not good enough it is better to use libuv for them.
Integration with new C++ features: Asio is better (Asio 1.51 extensively use C++11 asynchronous model, move semantics, variadic templates).In regard to maturity, Asio is a more stable and mature project with good documentation (if compare it to libuv headers description), a lot of information across the Internet (video talks, blogs: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg=1 ,etc.) and even books (not for professionals but nevertheless: http://en.highscore.de/cpp/boost/index.html ). Libuv has only one online book (but also good) http://nikhilm.github.com/uvbook/index.html and several video talks, so it will be difficult to know all the secrets (this library has a lot of them). For more specific discussion of functions see my comments below.
集成新的c++特性:Asio更好(Asio 1.51广泛使用c++异步模型、移动语义、可变模板)。就成熟度而言,Asio是一个更稳定、更成熟的项目,拥有良好的文档(如果与libuv header描述相比),它包含了互联网上的大量信息(视频对话,博客:http://www.gamedev.net/blog/950/entry-2249317-a-guide- get -started- boostasio?pg=1,等等),甚至书籍(不是为专业人士准备的,但是:http://en.highscore.de/cpp/boost/index.html)。Libuv只有一本在线图书(但也不错)http://nikhilm.github.com/uvbook/index.html和几个视频讲座,所以很难知道所有的秘密(这个图书馆有很多)。有关函数的更具体讨论,请参阅下面我的评论。
As conclusion, I should said that it all depends on your purposes, your project and what concretely you intend to do.
最后,我想说,这一切都取决于你的目的、你的项目以及你打算具体做什么。
#3
13
One huge difference is the author of Asio (Christopher Kohlhoff) is grooming his library for inclusion in the C++ Standard Library, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175.pdf and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
一个巨大的不同是,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/papers/papers/paper4370.html