从boost锁自由spsc队列中获得错误输出



我试图使用boost库实现用户定义数据类型的锁自由队列,但我得到错误的结果。

请告诉我哪里做错了。

#include <boost/lockfree/spsc_queue.hpp>
#include <thread>
#include <iostream>
#include <string.h>
#include <time.h>   

class Queue
{
 private:
       unsigned char *m_data;
       int m_len;
 public:
       Queue(unsigned char *data,int len);
       Queue(const Queue &obj);
       ~Queue();  
       Queue & operator =(const Queue &obj);

       unsigned char *getdata()
       {
         return m_data;
       }
       int getint()
       {
           return m_len;
       }
};
Queue::Queue(unsigned char* data, int len)
{
      m_len=len;
      m_data=new unsigned char[m_len];
      memcpy(m_data,data,m_len);
}
Queue::Queue(const Queue& obj)
{
      m_len=  obj.m_len;
      m_data=new unsigned char[m_len];
      memcpy(m_data,(unsigned char *)obj.m_data,m_len);
}
Queue::~Queue()
{
   delete[] m_data;
   m_len=0;
}
Queue & Queue::operator =(const Queue &obj)
{
   if(this != &obj)
   {
      m_len=obj.m_len;
      m_data=new unsigned char[m_len];
      memcpy(m_data,(unsigned char *)obj.m_data,m_len);
   }
   return *this;
}
boost::lockfree::spsc_queue<Queue*> q(10);

void produce()
{
    int i=0;
    unsigned char* data=(unsigned char *)malloc(10);
    memset(data,1,9);
    Queue obj(data,10);
    Queue *pqueue=&obj;
    printf("%dn",pqueue->getint());

    q.push(pqueue);
}
void consume()
{
    Queue *obj;
    q.pop(&obj);
    printf("%dn",obj->getint());
}

int main(int argc, char** argv) {

//  std::thread t1{produce};
//  std::thread t2{consume};
//  
//  t1.join();
//  t2.join();
    produce();
    consume();
    return 0;
}

根据boost::lockfree::队列要求,我在类中创建了以下内容。

  • 拷贝构造函数
  • 赋值操作符
  • 析构函数

如果还需要什么,请告诉我。谢谢。

  1. 你在c++中使用malloc

    你死。

    你还有2条命。

    说真的,别那样做。特别是因为它与delete[]一起使用是明确的未定义行为。


  2. 可悲的是你又失去了一条生命:

    Queue obj(data,10);
    Queue *pqueue=&obj;
    q.push(pqueue);
    

    存储一个指向本地的指针。更多未定义行为

    你还有1条命。


  3. 最后寿命

    q.pop(&obj);
    

    使用迭代器弹出。它将被视为输出迭代器。您将得到一个返回值,该值指示弹出的元素和项的数量将写入&obj[0], &obj[1], &obj[2]

    你猜怎么着?未定义的行为。

    参见:Boost spsc queue segfault

    你死了。


  4. 你已经死了。但你却放弃了来世

    printf("%dn",obj->getint());
    

    由于pop可能没有弹出任何东西(队列可能是空的),这本身就是未定义行为。


有趣的是,你讨论了所有这些构造函数的要求但是你把指针存储在无锁队列中…?!就这么写:

typedef std::vector<unsigned char> Data;
class Queue {
    private:
    Data m_data;
    public:
    Queue(Data data) : m_data(std::move(data)) {}
    Queue() : m_data() {}
    unsigned char const *getdata() const { return m_data.data(); } 
    size_t               getint()  const { return m_data.size(); } 
};
boost::lockfree::spsc_queue<Queue> q(10);

Live On Coliru

指出:

  • 需要让消费者检查pop的返回码。push可能没有发生,并且无锁队列不会阻塞。

  • 你不需要那个装置。直接传递矢量:

c++代码

Live On Coliru

#include <boost/lockfree/spsc_queue.hpp>
#include <thread>
#include <iostream>
#include <vector>
typedef std::vector<unsigned char> Queue;
boost::lockfree::spsc_queue<Queue> q(10);
void produce() {
    Queue obj(10, 1);
    std::cout << __FUNCTION__ << " - " << obj.size() << "n";
    q.push(std::move(obj));
}
void consume() {
    Queue obj;
    while (!q.pop(obj)) { }
    std::cout << __FUNCTION__ << " - " << obj.size() << "n";
}
int main() {
    std::thread t1 {produce};
    std::thread t2 {consume};
    t1.join();
    t2.join();
}

相关内容

  • 没有找到相关文章

最新更新