你可以試試這個..我只是寫的不是從頭開始。它是跨平臺的,所以這總是一個加號。分配器和池可以重用任何東西。例如,你可以做任何STL容器中的堆疊或任何你想要的分配..
SharedMemory.hpp:
#ifndef SHAREDMEMORY_HPP_INCLUDED
#define SHAREDMEMORY_HPP_INCLUDED
#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#include <string>
#include <cstdint>
class SharedMemory
{
private:
std::string name;
std::size_t size;
void* data;
void* hFileMap;
public:
SharedMemory(std::string name, std::size_t size) : name(name), size(size), data(nullptr), hFileMap(nullptr) {};
~SharedMemory();
bool Open();
bool Create();
std::size_t GetSize() const {return this->size;}
void* GetPointer() const {return this->data;}
};
#endif // SHAREDMEMORY_HPP_INCLUDED
SharedMemory.cpp:
#include "SharedMemory.hpp"
SharedMemory::~SharedMemory()
{
if (data)
{
#if defined _WIN32 || defined _WIN64
UnmapViewOfFile(data);
data = nullptr;
if (hFileMap)
{
if (CloseHandle(hFileMap))
{
hFileMap = nullptr;
}
}
#else
if (data)
{
munmap(data, size);
data = nullptr;
}
if (hFileMap)
{
if (!close(hFileMap))
{
hFileMap = nullptr;
}
}
#endif
}
}
bool SharedMemory::Open()
{
#if defined _WIN32 || defined _WIN64
if ((hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, name.c_str())) == nullptr)
{
return false;
}
if ((data = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, size)) == nullptr)
{
CloseHandle(hFileMap);
return false;
}
#else
if ((hFileMap = open(MapName.c_str(), O_RDWR | O_CREAT, 438)) == -1)
{
return false;
}
if ((data = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0)) == MAP_FAILED)
{
close(hFileMap);
return false;
}
#endif
return true;
}
bool SharedMemory::Create()
{
#if defined _WIN32 || defined _WIN64
if ((hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, size, name.c_str())) == nullptr)
{
return false;
}
if ((data = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, size)) == nullptr)
{
CloseHandle(hFileMap);
return false;
}
#else
if ((hFileMap = open(MapName.c_str(), O_RDWR | O_CREAT, 438)) == -1)
{
return false;
}
if ((data = mmap(nullptr, Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0)) == MAP_FAILED)
{
close(hFileMap);
return false;
}
#endif
return true;
}
Pools.hpp:
#ifndef POOLS_HPP_INCLUDED
#define POOLS_HPP_INCLUDED
#include <stdexcept>
#include <cstdint>
#include "SharedMemory.hpp"
template<typename T>
class SharedPool
{
private:
T* data;
SharedMemory* shm;
std::size_t size;
public:
SharedPool(SharedMemory* shm) : data(reinterpret_cast<T*>(shm->GetPointer())), shm(shm), size(shm->GetSize()) {};
template<typename U = T>
void* allocate(std::size_t n, const void* hint = 0) {return &data[0];}
template<typename U = T>
void deallocate(U* ptr, std::size_t n) {}
template<typename U = T>
std::size_t max_size() const {return size;}
};
#endif // POOLS_HPP_INCLUDED
main.cpp中(來自過程中的一個添加值以共享存儲器):
#include "SharedMemory.hpp"
#include "Allocators.hpp"
#include "Pools.hpp"
#include <vector>
#include <iostream>
int main()
{
SharedMemory mem = SharedMemory("Local\\Test_Shared_Memory", 1024);
if (!mem.Open() && !mem.Create())
{
throw std::runtime_error("Error Mapping Shared Memory!");
}
auto pool = PoolAllocator<int, SharedPool<int>>(SharedPool<int>(&mem));
std::vector<int, decltype(pool)> v(pool);
int* ptr = reinterpret_cast<int*>(mem.GetPointer());
std::cout<<"Pushing 3 values to: "<<ptr<<"\n";
v.push_back(100);
v.push_back(200);
v.push_back(700);
std::cin.get();
}
main.cpp中(共享內存的過程中有兩個讀數值):
#include "SharedMemory.hpp"
#include "Allocators.hpp"
#include "Pools.hpp"
#include <vector>
#include <iostream>
int main()
{
SharedMemory mem = SharedMemory("Local\\Test_Shared_Memory", 1024);
if (!mem.Open() && !mem.Create())
{
throw std::runtime_error("Error Mapping Shared Memory!");
}
auto pool = PoolAllocator<int, SharedPool<int>>(SharedPool<int>(&mem));
std::vector<int, decltype(pool)> v(pool);
int* ptr = reinterpret_cast<int*>(mem.GetPointer());
std::cout<<"Reading 3 values from: "<<ptr<<"\n";
v.reserve(3);
std::cout<<v[0]<<"\n";
std::cout<<v[1]<<"\n";
std::cout<<v[2]<<"\n";
std::cin.get();
}
線程將共享地址空間,所以他們沒有必要SHM的()(確保你知道,如果你是創建一個新的進程或線程),其餘的依賴於你的確切位置 - 它們是讀取還是寫入,還是兩者都有?等 – user3125280
使用共享內存不一定就夠了 - 特別是如果shm中的指針指向不共享的內存。這聽起來像你不應該使用進程 - 相反,你應該在同一個進程中使用線程(pthreads,或任何你的環境支持)。其中一個原因是共享全局空間只有在發生寫入時才共享......然後它是兩個獨立的內存緩衝區。 – mah
我使用fork來分支攜帶使用的輸入,然後根據這些輸入更新全局變量,然後啓動外部過程,然後終止子進程,這樣在下一個用戶輸入來臨之前,主進程知道到底是什麼在最後一次通話中繼續。我意識到,殘酷的分析將是在分叉之前進行更新,或者由於用戶輸入也被複制,讓孩子只調用外部程序,而主要更新變量。但是,我真的可以在孩子身上進行更新,而不是採用殘酷的解決方案嗎? – Sean