Create a shared-memory vector of strings
我正在尝试创建一个类来管理(std)字符串的共享内存向量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | typedef boost::interprocess::allocator<std::string, boost::interprocess::managed_shared_memory::segment_manager> shmem_allocator; typedef boost::interprocess::vector<std::string, shmem_allocator> shmem_vector; shmem_mgr::shmem_mgr() : shmem_(create_only, SHMEM_KEY, SHMEM_SIZE), allocator_(shmem_.get_segment_manager()) { mutex_ = shmem_.find_or_construct<interprocess_mutex>(SHMEM_MUTEX)(); condition_ = shmem_.find_or_construct<interprocess_condition>(SHMEM_CONDITION)(); //buffer_ is of type shmem_vector buffer_ = shmem_.construct<shmem_vector>(SHMEM_BUFFER_KEY)(allocator_); } void shmem_mgr::run() { running_ = true; while(running_) { scoped_lock<interprocess_mutex> lock ( *mutex_ ); int size = buffer_->size(); log_.debug() << size <<" queued request(s) found" << std::endl; //LINE 27 for(int i=0; i<size; i++) { log_.debug() << buffer_->at(i); // at() crashes my app } buffer_->clear(); //so does clear() condition_->wait (lock); } } |
客户端成功地向向量添加了一个字符串(它也成功地从缓冲区中读取了该字符串以进行调试),管理器(上面的代码)接收到信号(条件变量),并在向量中写入了一个字符串(第27行) ),但是当它尝试通过
编辑:我已经弄清楚,不可能使用
问:如何在共享内存之间传递字符串? 我需要将它们存储在shmem的某个缓冲区(一次可以存储> 1)中,然后在第二个进程中进行提取-这是必需的。 输入始终为
从文档。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/containers/vector.hpp> #include <boost/interprocess/containers/string.hpp> #include <boost/interprocess/allocators/allocator.hpp> int main () { using namespace boost::interprocess; //Typedefs typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator; typedef basic_string<char, std::char_traits<char>, CharAllocator> MyShmString; typedef allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator; typedef vector<MyShmString, StringAllocator> MyShmStringVector; //Open shared memory //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; managed_shared_memory shm(create_only,"MySharedMemory", 10000); //Create allocators CharAllocator charallocator (shm.get_segment_manager()); StringAllocator stringallocator(shm.get_segment_manager()); //This string is in only in this process (the pointer pointing to the //buffer that will hold the text is not in shared memory). //But the buffer that will hold"this is my text" is allocated from //shared memory MyShmString mystring(charallocator); mystring ="this is my text"; //This vector is only in this process (the pointer pointing to the //buffer that will hold the MyShmString-s is not in shared memory). //But the buffer that will hold 10 MyShmString-s is allocated from //shared memory using StringAllocator. Since strings use a shared //memory allocator (CharAllocator) the 10 buffers that hold //"this is my text" text are also in shared memory. MyShmStringVector myvector(stringallocator); myvector.insert(myvector.begin(), 10, mystring); //This vector is fully constructed in shared memory. All pointers //buffers are constructed in the same shared memory segment //This vector can be safely accessed from other processes. MyShmStringVector *myshmvector = shm.construct<MyShmStringVector>("myshmvector")(stringallocator); myshmvector->insert(myshmvector->begin(), 10, mystring); //Destroy vector. This will free all strings that the vector contains shm.destroy_ptr(myshmvector); return 0; } |
您可以使用boost :: interprocess :: managed_shared_memory。以下程序在两个进程之间传递了boost :: interprocess :: string。在我的计算机(Ubuntu Linux)上可以正常工作。
您可以使用managed_shared_memory传递矢量或对象。 boost :: interprocess :: string具有c_str()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/interprocess/containers/string.hpp> #include <cstring> #include <cstdlib> #include <string> #include <iostream> int main(int argc, char *argv[]) { using namespace boost::interprocess; typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> CharAllocator; typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> string; if(argc == 1){ //Parent process boost::interprocess::shared_memory_object::remove("MySharedMemory"); //Create a shared memory object. managed_shared_memory shm (create_only,"MySharedMemory", 1024); string *s = shm.find_or_construct<string>("String")("Hello!", shm.get_segment_manager()); std::cout << *s << std::endl; //Launch child process std::string s1(argv[0]); s1 +=" child"; if(0 != std::system(s1.c_str())) return 1; } else{ //Open already created shared memory object. managed_shared_memory shm (open_only,"MySharedMemory"); std::pair<string *,std::size_t> ret = shm.find<string>("String"); std::cout << *(ret.first) << std::endl; } return 0; } |
您需要为共享的stl类使用自定义分配器。您需要在分配器中定义一个基于自我的指针(ACE和boost具有这些指针)。 (连续)共享内存的相反两侧通常位于不同的地址。您还需要一个共享的内存分配子系统(堆管理器)(分配器从中分配)-所有非平凡的低级代码,但是最确定的是可行的,一旦有了它,它便可以在任何地方使用。如果执行所有这些操作,则只需要传递非平坦结构的位移(从(连续!)堆区域的开始)。
您可以创建队列以及可能需要的所有其他内容-只要对象中的"指针"是基于自身的,并且非扁平块中的不连续块来自一个大的连续块即可。
您不能使用std :: string,因为除非您控制分配,否则标准字符串中的内存与共享内存无关(与其他任何stl结构相同)
(通常)必须解决/同意所有权问题