All Projects → MengRao → Wfmpmc

MengRao / Wfmpmc

Licence: mit
A bounded wait-free(almost) zero-copy MPMC queue written in C++11, which can also reside in SHM for IPC

Projects that are alternatives of or similar to Wfmpmc

pe-util
List shared object dependencies of a portable executable (PE)
Stars: ✭ 45 (-28.57%)
Mutual labels:  shared-memory
Tcpshm
A connection-oriented persistent message queue framework based on TCP or SHM(shared memory)
Stars: ✭ 314 (+398.41%)
Mutual labels:  shared-memory
Ucx
Unified Communication X (mailing list - https://elist.ornl.gov/mailman/listinfo/ucx-group)
Stars: ✭ 471 (+647.62%)
Mutual labels:  shared-memory
mmap-object
Shared Memory Objects for Node
Stars: ✭ 90 (+42.86%)
Mutual labels:  shared-memory
speedtables
Speed tables is a high-performance memory-resident database. The speed table compiler reads a table definition and generates a set of C access routines to create, manipulate and search tables containing millions of rows. Currently oriented towards Tcl.
Stars: ✭ 56 (-11.11%)
Mutual labels:  shared-memory
Sharedhashfile
Share Hash Tables With Stable Key Hints Stored In Memory Mapped Files Between Arbitrary Processes
Stars: ✭ 380 (+503.17%)
Mutual labels:  shared-memory
MPSC Queue
A multi-producer single consumer queue C++ template suitable for async logging with SHM IPC support
Stars: ✭ 51 (-19.05%)
Mutual labels:  shared-memory
Pyopencl
OpenCL integration for Python, plus shiny features
Stars: ✭ 790 (+1153.97%)
Mutual labels:  shared-memory
Ecal
eCAL - enhanced Communication Abstraction Layer
Stars: ✭ 292 (+363.49%)
Mutual labels:  shared-memory
Cpp Ipc
C++ IPC Library: A high-performance inter-process communication using shared memory on Linux/Windows.
Stars: ✭ 420 (+566.67%)
Mutual labels:  shared-memory
hack parallel
The core parallel and shared memory library used by Hack, Flow, and Pyre
Stars: ✭ 39 (-38.1%)
Mutual labels:  shared-memory
shared memory
A Rust wrapper around native shared memory for Linux and Windows
Stars: ✭ 234 (+271.43%)
Mutual labels:  shared-memory
Libshmcache
libshmcache is a local cache in the share memory for multi processes. high performance due to read is lockless. libshmcache is 100+ times faster than a remote interface such as redis.
Stars: ✭ 385 (+511.11%)
Mutual labels:  shared-memory
IPC.Bond
IPC.Bond is an extension of IPC library that provides inter-process communication using shared memory on Windows with Bond serialization.
Stars: ✭ 26 (-58.73%)
Mutual labels:  shared-memory
Ems
Extended Memory Semantics - Persistent shared object memory and parallelism for Node.js and Python
Stars: ✭ 552 (+776.19%)
Mutual labels:  shared-memory
lua-shm-state-poc
Lua state in shared memory: a proof of concept
Stars: ✭ 22 (-65.08%)
Mutual labels:  shared-memory
Ipc
IPC is a C++ library that provides inter-process communication using shared memory on Windows. A .NET wrapper is available which allows interaction with C++ as well.
Stars: ✭ 332 (+426.98%)
Mutual labels:  shared-memory
Libandroid Shmem
System V shared memory emulation on Android using ashmem.
Stars: ✭ 53 (-15.87%)
Mutual labels:  shared-memory
Yac
A fast, lock-free, shared memory user data cache for PHP
Stars: ✭ 782 (+1141.27%)
Mutual labels:  shared-memory
Libvineyard
libvineyard: an in-memory immutable data manager.
Stars: ✭ 392 (+522.22%)
Mutual labels:  shared-memory

WFMPMC

WFMPMC is a wait-free(almost: reason) and zero-copy multiple producer multiple consumer queue template written in C++11.

It's also suitable for residing in shared memory in Linux for IPC

Usage

Both writer and reader need to call 3 member functions in sequence to complete one operation. Take writer for example:

  1. getWriteIdx() to allocate an index to write at.
  2. getWritable(idx) to get a writable pointer and user should construct the object referred to by the pointer. If the object at the index is not ready for writing(when the queue is full()) it'll return nullptr, and user can retry.
  3. commitWrite(idx) to commit the operation after writing is done.

Of course, all the 3 operations are wait-free.

WFMPMC<int, 8> q;

// write integer 123 into queue
auto idx = q.getWriteIdx();
int* data;
while((data = q.getWritable(idx)) == nullptr)
  ;
*data = 123;
q.commitWrite(idx);

...

// read an integer from queue
auto idx = q.getReadIdx();
int* data;
while((data = q.getReadable(idx)) == nullptr)
  ;
std::cout<< *data << std::endl;
q.commitRead(idx);

Note that the user defined type T doesn't require default constructor, but the pointer returned by getWritable(idx)(if successful) points to an unconstructed object, surprise? Thus user should construct it himself if necessary. See tor_test.cc.

If you find the API too tedious to use and don't care about the wait-free and zero-copy features, there're Lounger versions for you: emplace() and pop().

WFMPMC<int, 8> q;

// write integer 123 into queue
q.emplace(123)

...

// read an integer from queue
std::cout << q.pop() << std::endl;

There're also tryPush() and tryPop() which are not zero-copy but wait-free:

WFMPMC<int, 8> q;

// write integer 123 into queue
while(!q.tryPush(123))
  ;

...

// read an integer from queue
int data;
while(!q.tryPop(data))
  ;
std::cout << data << std::endl;

The implementation of Try API is a little bit tricky that it uses object scope thread local variables to save the index when a try is failed, and reuse it in the next try. It uses an open addressing hash table for searching thread ids, and the size of the hash table can be set by the third template parameter THR_SIZE.

Lastly, zero-copy try API was added which uses Visitor model: tryVisitPush(lambda)/tryVisitPop(lambda):

WFMPMC<int, 8> q;

// write integer 123 into queue
while(!q.tryVisitPush([](int& data){ data = 123; }))
  ;

...

// read an integer from queue
while(!q.tryVisitPop([](int&& data){ std::cout << data << std::endl; }))
  ;

Performance

Benchmark is done on an Ubuntu 14.04 host with Intel(R) Xeon(R) CPU E5-2687W 0 @ 3.10GHz.

Single thread write/read pair operation for int32_t takes 53 cycles. See bench.cc.

SHM IPC latency for transfering an 16 byte object is around 200 cycles when cpu cores are pinned properly, and the performance is not affected by the number of writers or readers, as long as there's at least one reader waiting for reading. See shm_writer.cc/shm_reader.cc.

A Pitfall for Shared Memory Usage

WFMPMC requires that the index acquired from getXXXIdx() must be committed by commitXXX(idx) later(Try API is similar that it must succeed eventually), otherwise the queue will be corrupted. If unfortunately, an program who has got an idx and is busy-waiting on it needs to shut down, it can't do it right away but still waiting to commit, and this could last infinitely.

Even worse, if a writer holding an index crashes before committing, then the corresponding reader will never succeed in reading one element even if other writer has completed a write operation. This is the reason why WFMPMC is not strict wait-free.

One way to mitigate this risk is to check if the operation is likely to wait before calling getXXXIdx(), that is, check empty() for reading and full() for writing. See shm_writer.cc/shm_reader.cc for details.

References

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].