Я реализую boost::circular_buffer
в boost::managed_shared_memory
, Я использовал пример кода, демонстрирующий вектор в разделяемой памяти Вот. Я сделал следующие изменения:
1) typedef boost::circular_buffer<int, ShmemAllocatorCB> MyCircularBuffer;
2) MyCircularBuffer *circbuff = segment.construct<MyCircularBuffer>("MyCB")(alloc_inst);
3) circbuff->push_back(1);
Код выдаёт ошибку компиляции в строке # 3. Ошибка
error C2665: 'operator new' : none of the 5 overloads could convert all the argument types c:\boost2005\boost\circular_buffer\base.hpp 1470
От документация, Я понимаю, что функция push_back ожидает одну из этих 3 форм:
void push_back(param_value_type);
void push_back(rvalue_type);
void push_back();
Я пробовал пустой вызов параметра, пытался привести 1 к param_value_type, rvalue_type, но ни один из них, похоже, не работает. Это может быть простой ошибкой, но я не могу понять это в течение достаточно долгого времени. Любая помощь приветствуется. Благодарю.
Редактировать:
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocatorCB;
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
const ShmemAllocatorCB alloc_inst (segment.get_segment_manager());
Похоже, что циклический буфер Boost использует необработанные указатели в какой-то момент времени для отладки. Это, к сожалению, недопустимо:
Boost предоставляет некоторые ссылки на эту тему:
Таким образом, скомпилируйте ваш код без поддержки отладки round_buffer, определив либо BOOST_CB_DISABLE_DEBUG
или же NDEBUG
препроцессор определяет.
(проверено с BOOST_LIB_VERSION
знак равно 1_49
)
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/circular_buffer.hpp>
#include <iostream>
#include <string>
#include <cstdlib> //std::system
using namespace boost::interprocess;
//Define an STL compatible allocator of ints that allocates from the managed_shared_memory.
//This allocator will allow placing containers in the segment
typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocatorCB;
//Alias a vector that uses the previous STL-like allocator so that allocates
//its values from the segment
typedef boost::circular_buffer<int, ShmemAllocatorCB> MyCircularBuffer;
//Main function. For parent process argc == 1, for child process argc == 2
int main(int argc, char *argv[])
{
if(argc == 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 new segment with given name and size
managed_shared_memory segment(create_only, "MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocatorCB alloc_inst (segment.get_segment_manager());
//Construct a buffer named "MyCB" in shared memory with argument 10 (for size) and alloc_inst
MyCircularBuffer *circbuff = segment.construct<MyCircularBuffer>("MyCB")(10, alloc_inst);
for(int i = 0; i < 100; ++i) //Insert data in the buffer, with overflows
circbuff->push_back(i);
//Launch child process
std::string s(argv[0]); s += " child ";
if(0 != std::system(s.c_str()))
return 1;
//Check child has destroyed the buffer
if(segment.find<MyCircularBuffer>("MyCB").first)
return 1;
}
else{ //Child process
//Open the managed segment
managed_shared_memory segment(open_only, "MySharedMemory");
//Find the buffer using the c-string name
MyCircularBuffer *circbuff = segment.find<MyCircularBuffer>("MyCB").first;
//Use buffer in reverse order
std::cout << "Child got: " << (*circbuff)[3] << "\n"; // 93
//When done, destroy the buffer from the segment
segment.destroy<MyCircularBuffer>("MyCB");
}
return 0;
};
Чтобы выполнить это:
g++ -DBOOST_CB_DISABLE_DEBUG -DNDEBUG cb_ipc.cpp -o cb_ipc -lboost_system -lrt
Чтобы запустить это:
./cb_ipc
Child got: 93
Проблема в том, что вы неправильно устанавливаете емкость циркулярного буфера. Я бы предположил, что емкость равна нулю, и, следовательно, вы не можете нажать.
После создания round_buffer установите емкость на нужный размер.
#define BOOST_CB_DISABLE_DEBUG
#include <boost/circular_buffer.hpp>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
using namespace boost;
using namespace boost::interprocess;
typedef allocator<T, managed_shared_memory::segment_manager> cb_alloc;
typedef circular_buffer<T, cb_alloc> cb;
managed_shared_memory* m_mem_segment;
cb* m_buffer;
// Create shared memory segment of a size able to hold the max updates.
m_mem_segment = new managed_shared_memory(open_or_create, NAMED_MEMORY, MEMORY_SIZE);
if (m_mem_segment == nullptr) {
return false;
}
// Get the segement manager for allocating a circular buffer.
const cb_alloc alloc_inst(m_mem_segment->get_segment_manager());
// Create a circular buffer in the shared memory segment.
m_buffer = m_mem_segment->find_or_construct<cb>(NAMED_BUFFER)(alloc_inst);
if (m_mem_segment == nullptr) {
return false;
}
// Set the capacity if not set (zero) (this must be set!)
if (m_buffer->capacity() <= 0) {
m_buffer->set_capacity(50);
}
Вы можете подтолкнуть к этому штрафу, я тестировал с несколькими процессами, обменивающимися данными отлично.
Это простой пример, очевидно, что вы должны реализовать свой собственный синхронизм между процессами с использованием named_mutex или семафоров и т. Д.