Multithreading Boost_lockFree_SPSC_队列是否真的大小可变且无数据丢失?

Multithreading Boost_lockFree_SPSC_队列是否真的大小可变且无数据丢失?,multithreading,c++11,boost,blockingqueue,Multithreading,C++11,Boost,Blockingqueue,您好,我计划使用BoostSPSC队列。我必须有一个监听器,它总是监听传入的消息,一旦它收到消息,它会将消息放入队列,然后返回等待新消息。还有一个消费者从队列中弹出消息并对其进行处理 因为我不想让我的侦听器等待将锁写入队列,所以我更喜欢boost\u lockfree\u spsc\u queue。我相信,如果在初始化队列时设置fixed\u size,队列的大小会有所不同。但事实似乎并非如此 以下是我的代码: boost::lockfree::spsc_queue<int, boost:

您好,我计划使用BoostSPSC队列。我必须有一个监听器,它总是监听传入的消息,一旦它收到消息,它会将消息放入队列,然后返回等待新消息。还有一个消费者从队列中弹出消息并对其进行处理

因为我不想让我的侦听器等待将锁写入队列,所以我更喜欢
boost\u lockfree\u spsc\u queue
。我相信,如果在初始化队列时设置
fixed\u size
,队列的大小会有所不同。但事实似乎并非如此

以下是我的代码:

boost::lockfree::spsc_queue<int, boost::lockfree::fixed_sized<false>> lockFreeQ{10};

void sharedQueue::lockFreeProduce()
{

    for(int i = 0; i < 100; i++)
    {
       lockFreeQ.push(i);        
       cout<<"--"<<i<<endl;
    }

}
void sharedQueue::lockFreeConsume(){

for(int i = 0;  i <100; i++){

   /* Implement a blocking pop to the queue in order to waste cpu time  by busy waiting*/

        while(!(lockFreeQ.read_available() > 0))
           {
               //std::this_thread::yield();
                 std::this_thread::sleep_for(std::chrono::nanoseconds(10));
           }

       cout<<"   ***"<<lockFreeQ.front()<<endl;
       lockFreeQ.pop();

   }

}

void sharedQueue:: TestLockFreeQueue()
{

   std::thread t1([this]() { this->lockFreeProduce(); });
   std::thread t2([this]() { this->lockFreeConsume(); });   
   t1.join();
   t2.join();
}
如果大小可变,则应扩展队列的大小,并且不应丢失数据。它似乎覆盖了所解释的数据。在这种情况下,如何在不丢失数据的情况下处理此问题


谢谢

将评论翻译成答案

该策略在
spsc_队列
中的工作方式如下:

typedef typename mpl::if_c<runtime_sized,                                  
                           runtime_sized_ringbuffer<T, allocator>,
                           compile_time_sized_ringbuffer<T, capacity>
                          >::type ringbuffer_type;

如果您真的需要一个无锁列表数据结构,您应该通过将注释翻译成答案来查看著名的无锁列表数据结构

该策略在
spsc_队列
中的工作方式如下:

typedef typename mpl::if_c<runtime_sized,                                  
                           runtime_sized_ringbuffer<T, allocator>,
                           compile_time_sized_ringbuffer<T, capacity>
                          >::type ringbuffer_type;

如果您确实需要一个无锁列表数据结构,您应该看看著名的无锁列表数据结构,您的队列仍然是一个循环缓冲区,最大大小为10。该策略唯一改变的是,它将使用动态分配的数组,而不是使用堆栈数组。您所说的“动态分配的数组”是什么意思?这是否意味着当队列已满时,数组的大小将增加?我的意思是数组将通过使用分配器进行分配。动态分配数组的大小将是您在构造函数中传递的大小。队列已满时,数组大小不会增加,相反,它将重写第一个索引上的数据,因为所使用的数据结构始终是一个循环缓冲区,大小与您在构造函数中传递的大小相同。因此,总结一下,在构造队列时,必须选择足够高的值,以确保在最佳情况下不会覆盖数据。基本上,使用循环队列无法保证这种行为,因为您永远不知道消费者何时会崩溃或开始缓慢处理。您的队列仍然是一个循环缓冲区,最大大小为10。该策略唯一改变的是,它将使用动态分配的数组,而不是使用堆栈数组。您所说的“动态分配的数组”是什么意思?这是否意味着当队列已满时,数组的大小将增加?我的意思是数组将通过使用分配器进行分配。动态分配数组的大小将是您在构造函数中传递的大小。队列已满时,数组大小不会增加,相反,它将重写第一个索引上的数据,因为所使用的数据结构始终是一个循环缓冲区,大小与您在构造函数中传递的大小相同。因此,总结一下,在构造队列时,必须选择足够高的值,以确保在最佳情况下不会覆盖数据。基本上,您无法使用循环队列来保证这种行为,因为您永远不知道消费者何时会崩溃或开始缓慢处理。
static size_t next_index(size_t arg, size_t max_size)
{
  size_t ret = arg + 1;
  while (unlikely(ret >= max_size))
    ret -= max_size;
  return ret;
}