如何在 C++ 中跨多个进程使用共享向量
How to use share vectors across multiple processes in C++
我在进程之间共享向量时遇到问题。
我可以共享向量,甚至可以从不同的进程中获取向量的大小,但是当我使用 at 函数时,程序就会崩溃。
struct B
{
std::vector<int> vec;
};
int main(int cArgs, char* ppszArgs[])
{
if (cArgs == 1) { //Parent process
//Remove shared memory on construction and destruction
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
} remover;
//Create a shared memory object.
shared_memory_object shm(create_only, "MySharedMemory", read_write);
//Set size
shm.truncate(1000);
//Map the whole shared memory in this process
mapped_region region(shm, read_write);
//Write all the memory to 1
B* test = new B();
CopyMemory(region.get_address(), test, sizeof(B));
parentProcess(); -> this method just starts the child process
int index = 1;
while (true)
{
if(index < 2)
{
((B*)region.get_address())->vec.push_back(index);
}
++index;
}
}
else
{
//Open already created shared memory object.
shared_memory_object shm(open_only, "MySharedMemory", read_only);
//Map the whole shared memory in this process
mapped_region region(shm, read_only);
//Check that memory was initialized to 1
HANDLE mem = region.get_address();
while(true)
{
std::cout << ((B*)mem)->vec.at(0) << std::endl; -> if for example i put
lista.size(), then i will get the number of items in vector.
}
}
}
我的问题是甚至可以从子进程访问向量元素吗?
是的,你绝对可以做到。您需要使用 boost 进程间库。您需要 (1) 一个互斥锁来仲裁对向量的访问,以及 (2) 您需要能够在共享内存中分配向量元素。您应该能够在一段共享内存中执行此操作。但是我无法在短时间内让它工作。这是使用两个共享内存段的解决方案,一个用于互斥量,一个用于向量。
#include <iostream>
#include <string>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp>
using namespace boost::interprocess;
typedef allocator<int, managed_shared_memory::segment_manager>
ShmemAllocator;
typedef std::vector<int, ShmemAllocator> MyVector;
struct B
{
boost::interprocess::interprocess_mutex mutex;
};
int main(int cArgs, char* ppszArgs[])
{
if (cArgs== 1) { //Parent process
std::cout << "In parent" << std::endl;
//Remove shared memory on construction and destruction
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MutexMemory"); }
~shm_remove() { shared_memory_object::remove("MutexMemory"); }
} remover;
shared_memory_object::remove("VectorMemory");
managed_shared_memory segment
(create_only
, "VectorMemory" //segment name
, 65536); //segment size in bytes
const ShmemAllocator alloc_inst(segment.get_segment_manager());
shared_memory_object shm(create_only, "MutexMemory", read_write);
MyVector* myvector =
segment.construct<MyVector>("MyVector") //object name
(alloc_inst);//first ctor parameter
shm.truncate(1000);
mapped_region region(shm, read_write);
void* addr = region.get_address();
B* test = new (addr) B();
// parentProcess(); -> this method just starts the child process
int index = 1;
while (true)
{
if (index < 10000)
{
scoped_lock<interprocess_mutex> lock(test->mutex);
myvector->push_back(index);
}
Sleep(1000);
++index;
}
}
else
{
std::cout << "In child" << std::endl;
//Open already created shared memory object.
shared_memory_object shm(open_only, "MutexMemory", read_write);
//Map the whole shared memory in this process
mapped_region region(shm, read_write);
B* mem = (B*)region.get_address();
managed_shared_memory segment
(open_only
, "VectorMemory"); //segment name
MyVector* myvector = segment.find<MyVector>("MyVector").first;
while (true)
{
if(1)
{
scoped_lock<interprocess_mutex> lock(mem->mutex);
std::cout << (myvector->size() == 0 ? -1 : (*myvector)[myvector->size() - 1]) << std::endl;
}
Sleep(1000);
}
}
}
我在进程之间共享向量时遇到问题。 我可以共享向量,甚至可以从不同的进程中获取向量的大小,但是当我使用 at 函数时,程序就会崩溃。
struct B
{
std::vector<int> vec;
};
int main(int cArgs, char* ppszArgs[])
{
if (cArgs == 1) { //Parent process
//Remove shared memory on construction and destruction
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
} remover;
//Create a shared memory object.
shared_memory_object shm(create_only, "MySharedMemory", read_write);
//Set size
shm.truncate(1000);
//Map the whole shared memory in this process
mapped_region region(shm, read_write);
//Write all the memory to 1
B* test = new B();
CopyMemory(region.get_address(), test, sizeof(B));
parentProcess(); -> this method just starts the child process
int index = 1;
while (true)
{
if(index < 2)
{
((B*)region.get_address())->vec.push_back(index);
}
++index;
}
}
else
{
//Open already created shared memory object.
shared_memory_object shm(open_only, "MySharedMemory", read_only);
//Map the whole shared memory in this process
mapped_region region(shm, read_only);
//Check that memory was initialized to 1
HANDLE mem = region.get_address();
while(true)
{
std::cout << ((B*)mem)->vec.at(0) << std::endl; -> if for example i put
lista.size(), then i will get the number of items in vector.
}
}
}
我的问题是甚至可以从子进程访问向量元素吗?
是的,你绝对可以做到。您需要使用 boost 进程间库。您需要 (1) 一个互斥锁来仲裁对向量的访问,以及 (2) 您需要能够在共享内存中分配向量元素。您应该能够在一段共享内存中执行此操作。但是我无法在短时间内让它工作。这是使用两个共享内存段的解决方案,一个用于互斥量,一个用于向量。
#include <iostream>
#include <string>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp>
using namespace boost::interprocess;
typedef allocator<int, managed_shared_memory::segment_manager>
ShmemAllocator;
typedef std::vector<int, ShmemAllocator> MyVector;
struct B
{
boost::interprocess::interprocess_mutex mutex;
};
int main(int cArgs, char* ppszArgs[])
{
if (cArgs== 1) { //Parent process
std::cout << "In parent" << std::endl;
//Remove shared memory on construction and destruction
struct shm_remove
{
shm_remove() { shared_memory_object::remove("MutexMemory"); }
~shm_remove() { shared_memory_object::remove("MutexMemory"); }
} remover;
shared_memory_object::remove("VectorMemory");
managed_shared_memory segment
(create_only
, "VectorMemory" //segment name
, 65536); //segment size in bytes
const ShmemAllocator alloc_inst(segment.get_segment_manager());
shared_memory_object shm(create_only, "MutexMemory", read_write);
MyVector* myvector =
segment.construct<MyVector>("MyVector") //object name
(alloc_inst);//first ctor parameter
shm.truncate(1000);
mapped_region region(shm, read_write);
void* addr = region.get_address();
B* test = new (addr) B();
// parentProcess(); -> this method just starts the child process
int index = 1;
while (true)
{
if (index < 10000)
{
scoped_lock<interprocess_mutex> lock(test->mutex);
myvector->push_back(index);
}
Sleep(1000);
++index;
}
}
else
{
std::cout << "In child" << std::endl;
//Open already created shared memory object.
shared_memory_object shm(open_only, "MutexMemory", read_write);
//Map the whole shared memory in this process
mapped_region region(shm, read_write);
B* mem = (B*)region.get_address();
managed_shared_memory segment
(open_only
, "VectorMemory"); //segment name
MyVector* myvector = segment.find<MyVector>("MyVector").first;
while (true)
{
if(1)
{
scoped_lock<interprocess_mutex> lock(mem->mutex);
std::cout << (myvector->size() == 0 ? -1 : (*myvector)[myvector->size() - 1]) << std::endl;
}
Sleep(1000);
}
}
}