ipcq
ipcq is not appropriate for all use-cases. Design trade-offs were made to achieve the following:
- Single producer, multiple consumer (SPMC).
- Templated element type that satisfies the TriviallyCopyable requirements.
- No error propagation from reader to writer or other readers (the queue is optionally lock free for this reason). This includes starvation due to holding locks.
- Support write frequencies in the kHz range with element size in the 0.5 - 1 MiB range (note that there is no strict limit that constrain user defined types).
- Reader can copy a subset of the full element type.
- Note
- ipcq use atomic operations and memory barriers for synchronization, which due to cache coherency protocols is almost always guaranteed not to be optimal. The choice was made to be able to guarantee that readers cannot block the writer.
The ipcq::Writer is located in ipcq/src/include/ipcq/writer.hpp. The ipcq::Reader is located in ipcq/src/include/ipcq/reader.hpp.
The details around shared memory management is located in ipcq/src/include/ipcq/detail/shm.hpp.
Dependencies
Library dependencies:
boost (mainly boost::interprocess)
NUMA++
Basic Usage
See also demo application in separate "tools" project.
The following shows the most basic use:
#include <array>
#include <cstdint>
};
std::array<float, 64 * 64>
data;
};
int main() {
auto capacity = 64u;
{
if (ec) {
std::cerr << "Failed to write to queue: " << ec.message() << std::endl;
return 1;
}
}
{
using namespace std::chrono_literals;
auto [ec, count] =
reader.Read([&out](
MyElement const& in)
noexcept { out = in; }, 1u, 10ms);
if (ec) {
std::cerr << "Failed to read from queue: " << ec.message() << std::endl;
return 1;
} else {
}
}
}
BasicReader< T, detail::BoostConditionPolicy > Reader
Convenience alias with reasonable default condition policy.
BasicWriter< T, BoostConditionPolicy > Writer
Convenience alias with reasonable default condition policy.
@ All
Notify all waiting readers.
Contains definition of ipcq::BasicReader.
std::array< float, 64 *64 > data
Contains declarations for ipcq::BasicWriter.
To read a batch consider the following (incomplete) example:
#include <chrono>
std::array<uint8_t, 128>
data;
};
void Writer() {
auto capacity = 64u;
if (err) {
}
}
void Reader() {
using namespace std::chrono_literals;
std::array<MyElement, 40> elements;
auto [err, count] =
if (err) {
} else {
}
}
Provides iterator adapter for ipcq::BasicReader.
static BasicReader MakeReader(char const *topic_name, std::chrono::duration< Rep, Period > timeout)
Adapts either LegacyOutputIterator or Iterator type (e.g.
Debugging Tool
The debug tool ipcq-spy is available, which can attach to any ipcq topic, irrespective of the contained types. It cannot be notified of availabillity of new data and will simply poll at a given interval. Nevertheless it is possible to tell if data is being written, together with other additional information.
Example output when spying on the ipcq-demo topic from the ipcq-demo application:
$ ipcq-spy
topic-name ipcq-demo
owner-pid 30258
owner-cmdline ipcq-demo writer
shm-size 37.61Mib
(39435624b)
shm-capacity 700
element-size 55.02kib
(56336b)
element-type-name GenericTopic<14080ul>
(12GenericTopicILm14080EE)
condition-type-name ipcq::detail::BoostConditionPolicy
(N4ipcq6detail20BoostConditionPolicyE)
shm-numa-map (ctl) 7f0e12e24000 default file=/dev/shm/ipcq-ipcq-demo dirty=1 mapmax=4 active=0 N0=1
kernelpagesize_kB=4
shm-numa-map (data) 7f0e0efbe000 default file=/dev/shm/ipcq-ipcq-demo dirty=193 mapped=9628 mapmax=4
active=0 N0=193 N1=9435 kernelpagesize_kB=4
stop spying with CTRL-C
[/] last internal counter value: 709, avg. freq: 631.6