Comparing Boost.Asio, libunifex, liburing, and CppCoro
Asked Answered
V

2

13

I am trying to understand asynchronous models in C++. I am investigating 4 libraries that purport to deal with asynchronous I/O:

  1. liburing (C version, C++ version): provides an interface for io_uring. The C++ version uses coroutines.
  2. libunifex: implements the C++ sender/receiver async programming model
  3. Boost.Asio: library for asynchronous network and low-level I/O programming
  4. CppCoro: provides a large set of general-purpose primitives for making use of coroutines

These libraries have an enormous amount of overlap.

Execution context and io_uring

The future of asynchronous I/O will likely use io_uring on Linux machines. liburing exists to provide an interface for io_uring with io_service. However, libunifex also provides io_uring_context. These both explicitly use io_uring but have usage similar to Boost.Asio's io_context and CppCoro's io_service.

Can liburing's io_service, libunifex's io_uring_context Boost.Asio's io_context, and CppCoro's io_service all be used together? If my code included all four of these libraries, would I have 1 execution context from each?

Functionality: opening files

This section contains an example of how CppCoro asynchronously opens a file. I believe this template class would be used in Boost.Asio for asynchronous file access. libunifex has an io_uring_text.cpp doc that includes asynchronous writes to files. Obviously liburing exists for asynchronously writing files.

Should I only use the io_uring specific libraries for file access?

Functionality: networking

Everyone knows that Boost.Asio provides networking functionality. CppCoro does too. The liburing GitHub includes an example echo server that uses low-level C code.

Linbunifex does not appear to include direct networking functionality. I presume it is meant to be combined with some other networking library. Would I combine it with one of the above three libraries to give an old library a sender-receiver interface? How would I do that?

Interface: coroutines

I'm guessing that coroutines are meant to be glue that allows these libraries to exist together. Boost.Asio is compatible with coroutines. liburing4cpp and libunifex have coroutine compatibility as a central feature. CppCoro, on the other hand, is essentially a coroutine library.

Does it at all make sense to talk about using coroutines as glue? Could I say "I will use library A to implement the async function and library B to handle the output of the async function"?

My Questions

Would you expect to see someone use all 4 of these libraries simultaneously? Are any of these libraries meant to be used on top of any of the others?

In cases where functionality overlaps, how do these libraries compare on performance? Is Boost.Asio falling behind new asynchronous models? Is Boost.Asio staying ahead by integrating the most recent asynchronous models? liburing4cpp included a low-level echo server that isn't much comparable to the modern interface of Boost.Asio. How do applications based on low-level io_uring usage compare to applications built using Boost.Asio?

I believe that senders/receivers in libunifex is primarily meant as an interface. Should I use it as an interface to other libraries, for example Boost.Asio?

Vacation answered 26/7, 2022 at 19:18 Comment(6)
To the person who voted to close: How do you propose breaking this question up into multiple questions? Should I have 6 questions each about a pair of libraries?Vacation
You are more or less asking for a recommendation, which library to use finally. That's off-topic here, sorry (the other close voter)Fourpence
I have no proposal on how you ask these 14 questions, but Stack Overflow is not designed to handle "multiple questions in one", as the site phrases it. You may be able to consolidate some of your questions into one, while other questions like "Should I..." and "Would you expect to see ..." are probably a matter of opinion, and off-topic for that reason.Mandel
@πάνταῥεῖ I can remove the parts about performance comparisons, but this question is very much about how these libraries are supposed to be used. liburing is an interface for io_uring. Senders/receivers is an interface for i/o. Does it make sense to use Boost.Asio on top of Libunifex on top of io_uring? or is it Libunifex on top of Boost.Asio on top of io_uring? Lewis Baker worked on Libunifex and CppCoro. Was Libunifex supposed to replace CppCoro with a Sender/Receiver interface? So does Boost.Asio on top of Libunifex on top of io_uring make sense? What do I do about the execution contexts?Vacation
These questions are essentially about the async model in theory and practice. I think all of these questions can be asked without asking which library to use. I think I did that in the OP.Vacation
Asking more than one question, is considered being too broad here anyways. Ask one question per question.Fourpence
G
2

Look at asio-grpc, I think they had almost all of your comparisons in examples

Glaydsglaze answered 26/7, 2022 at 19:46 Comment(0)
I
0

A performance comparison for some concurrency model and coroutine libs.

https://github.com/alibaba/PhotonLibOS#21-tcp

Iverson answered 28/2, 2023 at 3:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.