但是,我希望子进程在双向链表的末尾插入一个元素。指向列表的第一个元素是全局的,我想从主进程访问所有列表元素,并且下次使用fork分支main时,我希望能够访问所有元素,并更新它们,并插入更多元素,反过来主要进程再次能够访问修改后的列表。
每个进程都使用execvp进行系统调用(我需要它们能够使用不同数量的参数调用内容)。
我可能会问一个太广泛的问题,但我个人没有比分支和在列表末尾插入元素更进一步。因此,我实际上没有一行代码可以将我带到我想去的地方。我不知道如何在这种情况下使用shm()。
请帮忙。
答案 0 :(得分:2)
你可以尝试这个..我只是从头开始写它。它是跨平台的,所以总是一个加号。分配器和池可以重复使用。例如,您可以在堆栈上或任何您想要的地方分配任何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(从进程1向共享内存添加值):
#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(从共享内存中读取值的过程2):
#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();
}
答案 1 :(得分:1)
这是一个棘手的问题。
一种方法是使用Shared Memory,在构建链表时,给它自己的分配器,以使用共享内存。其他方法是根据共享内存实现自己的链表。
你也可以尝试使用boost - Boost interprocess,这可能是理想的解决方案。
具体而言 - interprocess with containers