Skip to content

Instantly share code, notes, and snippets.

@ProfAvery
Last active October 12, 2020 01:03
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 ProfAvery/c152509537ab875b33230a6df344dc5e to your computer and use it in GitHub Desktop.
Save ProfAvery/c152509537ab875b33230a6df344dc5e to your computer and use it in GitHub Desktop.
POSIX Shared Memory Example
*.o
send_string
receive_string
CXXFLAGS = -g -std=c++17 -Wall -Wextra -Wpedantic
TARGETS = send_string receive_string
LDLIBS = -lrt
MESSAGE = "Testing 1...2...3..."
.PHONY: test clean
all: $(TARGETS)
send_string: send_string.o shm.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)
receive_string: receive_string.o shm.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)
SHELL = /bin/bash
test: $(TARGETS)
./send_string $(MESSAGE)
diff <(echo $(MESSAGE)) <(./receive_string)
clean:
rm -f *.o $(TARGETS)
#include <cstdlib>
#include <iostream>
#include "shm.h"
using std::cout;
using std::endl;
const auto REGION_SIZE = 4096;
const auto REGION_NAME = "MESSAGE";
const auto REGION_PERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int main()
{
SharedMemory region(
REGION_NAME,
O_RDONLY,
REGION_PERMS,
REGION_SIZE,
PROT_READ
);
char *buffer = reinterpret_cast<char *>(region.ptr);
cout << buffer << endl;
region.unlink();
return EXIT_SUCCESS;
}
#include <cstdlib>
#include <cstring>
#include <iostream>
#include "shm.h"
using std::cerr;
using std::endl;
const auto REGION_SIZE = 4096;
const auto REGION_NAME = "MESSAGE";
const auto REGION_PERMS = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ;
int main(int argc, char *argv[])
{
if (argc != 2) {
cerr << "Usage: " << argv[0] << " MESSAGE" << endl;
return EXIT_FAILURE;
}
auto message = argv[1];
auto len = strlen(message);
if (len > REGION_SIZE - 1) {
cerr << "Message too long." << endl;
return EXIT_FAILURE;
}
SharedMemory region(
REGION_NAME,
O_CREAT | O_RDWR,
REGION_PERMS,
REGION_SIZE,
PROT_READ | PROT_WRITE);
char *buffer = reinterpret_cast<char *>(region.ptr);
snprintf(buffer, REGION_SIZE, "%s", message);
return EXIT_SUCCESS;
}
#include <cstdlib>
#include <sys/types.h>
#include <unistd.h>
#include "shm.h"
SharedMemory::SharedMemory(std::string name, int oflag, mode_t mode, size_t length, int prot)
{
this->name = name;
fd = shm_open(name.c_str(), oflag, mode);
if (fd < 0) {
perror("shm_open");
exit(EXIT_FAILURE);
}
if ((oflag & O_CREAT) == O_CREAT) {
auto ok = ftruncate(fd, length);
if (ok < 0) {
perror("ftruncate");
exit(EXIT_FAILURE);
}
}
ptr = mmap(NULL, length, prot, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
}
void SharedMemory::unlink()
{
auto ok = shm_unlink(name.c_str());
if (ok < 0) {
perror("shm_unlink");
exit(EXIT_FAILURE);
}
}
#ifndef SHM_H
#define SHM_H
#include <string>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
class SharedMemory {
public:
SharedMemory(std::string, int, mode_t, size_t, int);
void unlink();
void *ptr;
private:
int fd;
std::string name;
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment