镜像自: https://github.com/DragonOS-Community/thingbuf.git
|
3 жил өмнө | |
---|---|---|
.github | 3 жил өмнө | |
assets | 3 жил өмнө | |
bench | 3 жил өмнө | |
bin | 3 жил өмнө | |
src | 3 жил өмнө | |
tests | 3 жил өмнө | |
.envrc | 3 жил өмнө | |
.gitignore | 3 жил өмнө | |
Cargo.toml | 3 жил өмнө | |
README.md | 3 жил өмнө | |
default.nix | 3 жил өмнө | |
mpsc_perf_comparison.md | 3 жил өмнө | |
netlify.toml | 3 жил өмнө | |
shell.nix | 3 жил өмнө |
"I'm at the buffer pool. I'm at the MPSC channel. I'm at the combination MPSC channel and buffer pool."
thingbuf
is a lock-free array-based concurrent ring buffer that allows access
to slots in the buffer by reference. It's also asynchronous
and blocking bounded MPSC channels implemented using
the ring buffer.
thingbuf::mpsc
has both. See
here for a detailed performance comparison of MPSC
channels. thingbuf::mpsc
is a competitive choice for a general-purpose
MPSC channel in most use cases.Both asynchronous and blocking
MPSC channels are available[^blocking-std], so thingbuf
can be used in place
of asynchronous channels like futures::channel::mpsc
and blocking
channels like std::sync::mpsc::sync_channel
.
If you can't allocate or you need to build with #![no_std]
because
you're working on embedded systems or other bare-metal software. Thingbuf
provides a statically-allocated MPSC channel and a
statically-allocated lock-free queue. These can be placed in a
static
initializer and used without requiring any runtime allocations.
You want to use the same MPSC channel with and without std
. Thingbuf's
asynchronous MPSC channel provides an identical API and feature set regardless
of whether or not the "std" feature flag is enabled. If you're writing a library that
needs to conditionally support #![no_std]
, and you need an asynchronous MPSC
channel, it might be easier to use thingbuf::mpsc
in both cases, rather
than switching between separate std
and #![no_std]
channel
implementations.
It's equally important to discuss when thingbuf
should not be used. Here are
some cases where you might be better off considering other options:
thingbuf::mpsc
might not be the best choice.Thingbuf's channels will allocate an array with length equal to the capacity
as soon as they're constructed. This improves performance by avoiding
additional allocations, but if you need to set very high bounds, you might
prefer a channel implementation that only allocates memory for messages as
it's needed (such as tokio::sync::mpsc
).
send_timeout
or a blocking channel
with a select
operation. I'm probably not going to implement these things.
The blocking channel isn't particularly important to me compared to the async
channel, and I probably won't add a bunch of additional APIs to it.If you need a synchronous channel with this kind of functionality,
crossbeam-channel
is probably a good choice.
A: For tracing
, I wanted to be able to send formatted log lines to a
dedicated worker thread that writes them to a file. Right now, we do this
using crossbeam-channel
. However, this has the sad disadvantage that we have
to allocate String
s, send them through the channel to the writer, and
immediately drop them. It would be nice to do this while reusing those
allocations. Thus...StringBuf
.
A: Extremely.
A: As long as you don't use the APIs that wait :)
A: Because unbounded queues are of the Devil.
A: If you use it wrong, yes.
A: Originally, I imagined it as a kind of ring buffer, so (as a pun on "ringbuf"), I called it "stringbuf". Then, I realized you could do this with more than just strings. In fact, it can be generalized to arbitrary...things. So, "thingbuf".
[^blocking-std]: The synchronous (blocking) channel naturally requires std
in
order to park threads.