【问题标题】:boost circular_buffer push_back compilation errorboost circular_buffer push_back 编译错误
【发布时间】:2014-06-30 07:46:09
【问题描述】:

我在boost::managed_shared_memory 中实现boost::circular_buffer。我使用了在共享内存here 中演示向量的示例代码。我做了以下更改:

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

从documentation,我了解到 push_back 函数需要以下三种形式之一:

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());

【问题讨论】:

  • 嗯,问题似乎是构造对象而不是推动它。如果您在 push_back 调用中发表评论,我怀疑该错误将持续存在。我认为您需要详细说明。特别是:ShmemAllocatorCB 是如何定义的,alloc_inst 是什么?
  • @hfhc2 :请检查编辑。该错误是在 push_back() 调用中准确引入的。如果我把它注释掉,程序编译就好了。

标签: c++ boost circular-buffer


【解决方案1】:

看起来 Boost 的循环缓冲区在某个时间点使用原始指针进行调试。不幸的是,这令人望而却步:

Boost 提供了一些关于该主题的参考:

总而言之,通过定义 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

【讨论】:

  • 打败我。如果只有一个消费者/生产者,Boost Lockfree 中还有 spsc_queue 可以满足此目的:stackoverflow.com/questions/22207546/…
  • 所有这些疯狂的 IPC 方式!绝对疯了!
  • @ftwl :感谢您的建议,但我已经尝试过了,但它不起作用。虽然奇怪的是,如果我将构建设置更改为 Release 而不是 Debug,错误会更改为 none of the 4 overloads could convert all the argument types 。
  • @sehe:感谢 spsc 队列建议,我会尝试一下。虽然,您能否就原始问题发表评论。我尝试使用预处理器,但没有奏效。
  • @Maverick 答案已经给出了解释,否则我会发布完全相同的答案。是的,这使得代码可以编译。
【解决方案2】:

这里的问题是您没有正确设置循环缓冲区的容量。我想容量为零,因此您无法推动。

在构建了 circular_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 或信号量等在进程之间实现自己的同步。

【讨论】:

    猜你喜欢
    • 2016-11-20
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多