Let's say I have a process A and a process B, and process A would like to pass a C string to process B through a shm_open() + mmap() shared memory.
What's the most latency efficient way?
The answer of this post suggested that after C++11, std::atomic is the right way to share data over shared memory.
However, I fail to see how I can write something to write a C string with something like this:
struct Buffer {
std::atomic<uint32_t> length;
std::atomic<char*> str;
} __attribute__((packed));
Given I have a shared memory created this way:
class SHM {
char* _ptr;
public:
SHM() {
const auto handle = shm_open("myTest", O_RDWR|O_CREAT, 0666);
const auto size = 4 * 1024 * 1024;
if (-1 == ftruncate(handle, size)) {
throw;
}
_ptr = (char*)mmap(0,size , PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);
if(_ptr == MAP_FAILED){
throw;
}
int rc = fchmod(handle, 0666);
if (rc == -1) {
throw;
}
}
// assume to caller will do buffer.size.store(someLength, std::memory_order_release); after filling up Buffer::str
Buffer& getBuffer() noexcept {
return *reinrepret_cast<Buffer*>(_ptr);
}
Buffer& read() {
auto& buffer = *reinrepret_cast<Buffer*>(_ptr);
while (buffer.size.load(std::memory_order_acquire) > 0) {
buffer.str.load(std::memory_order_relaxed);
return buffer;
}
}
};
How can the caller to SHM::getBuffer()
properly write to Buffer::str char by char so that process B can call SHM::read()
to retrieve?
Does buffer.str.load(std::memory_order_relaxed) actually load atomically and correctly? I doubt that as it doesn't even know the length.
This is for Linux, X86-64, GCC 7.
Thanks in advance.