Skip to content

Instantly share code, notes, and snippets.

@saleph
Created April 23, 2017 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saleph/9c852977183bf49e335a7c1ab51e3d51 to your computer and use it in GitHub Desktop.
Save saleph/9c852977183bf49e335a7c1ab51e3d51 to your computer and use it in GitHub Desktop.
//sharedmemory.h
#ifndef SHAREDMEMORY_H
#define SHAREDMEMORY_H
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
#include <vector>
#include <algorithm> //for std::generate_n
#include <string>
#include <cstdio>
class SharedMemory
{
const char *SHM_NAME;
void *memory;
size_t size;
pid_t creator;
std::vector<pid_t> processesWithAccess;
public:
// !!! ctor should be only called in Parent thread !!!
// shared memory is being accessable as long as parent does not destruct the object
SharedMemory(size_t s);
~SharedMemory();
// can be called multiple times
void *getPtr();
private:
void *getSHM();
static const char *getRandomMemoryName(size_t len);
};
#endif // SHAREDMEMORY_H
// =============================================================================
// sharedmemory.cpp
#include "sharedmemory.h"
SharedMemory::SharedMemory(size_t s)
: SHM_NAME(getRandomMemoryName(100)), creator(getpid()), size(s) {
// via fork() address space is being duplicated -
// so no second construction occurs and only owner (parent)
// has right to unlink shared memory
// children has "creator" member set to pid of parent
// random memory name allows to create multiple memories in the same parent
// (and even children can create own shared memory, which can be shared with
// children's children)
}
SharedMemory::~SharedMemory() {
shmdt(memory);
if (getpid() == creator) {
shm_unlink(SHM_NAME);
}
}
void *SharedMemory::getPtr() {
pid_t thisProc = getpid();
for (auto&& p : processesWithAccess) {
if (p == thisProc) {
return memory;
}
}
memory = getSHM();
processesWithAccess.push_back(thisProc);
return memory;
}
void *SharedMemory::getSHM() {
int shm;
void *memory;
shm = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRWXU | S_IRWXO);
ftruncate(shm, size);
memory = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, shm, 0);
return memory;
}
const char *SharedMemory::getRandomMemoryName(size_t len)
{
srand(time(NULL));
auto randchar = []() -> char
{
const char charset[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
const size_t max_index = (sizeof(charset) - 1);
return charset[ rand() % max_index ];
};
std::string str(len,0);
std::generate_n( str.begin(), len, randchar );
str = "/" + str;
return str.data();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment