Boost spsc queue segfault

2019-08-13 12:17发布

问题:

I've tried to use boost::lockfree::spsc_queue. Occasinally found segfault, when used it with std::vector<uint16_t>. The whole type is:

spsc_queue<vector<uint16_t>, boost::lockfree::capacity<1000>> queue;

Debugging showed, that segfault happend on pop, which was organized this way:

vector<uint16_t> vec;
while(!done)
  while(quuee.pop(&vec)){ /* do staff */}

Documentation on spsc_queue says:

bool pop(T & ret);

Pops one object from ringbuffer.

But, when I use

vector<uint16_t> vec;
while(!done)
  while(quuee.pop(&vec,1)){
    /* do staff */
  }

Segfault magically disappears. This makes me thinking, that bool pop(T&) somehow tries to restore as many items as possible.

Am I correctly use this container? Is this issue should happen to vector-like containers only? Is that staff rarely used, so it is buggy? What caveats I could face when I'm using it with vectors?

回答1:

Segfault magically disappears. This makes me thinking, that bool pop(T&) somehow tries to restore as many items as possible.

That's magical thinking. It's not true

Am I correctly use this container?

We can't tell because you don't show how you're using it. (Only a fragment)

Is this issue should happen to vector-like containers only? Is that staff rarely used, so it is buggy?

Magical thinking again

What caveats I could face when I'm using it with vectors?

The same as with other types: Did you violate the threading invariants? Do you read from 1 single thread, and write from 1 single other thread?

UPDATE

Thanks for adding a SSCCE.

It was indeed a subtle bug in usage (I missed it earlier). You're passing a pointer to value and the queue element type is not convertible to that.

That means that the single-value overload is not applicable.

The overload that is taken is the the single-argument overload taking an OutputIterator.

template<typename OutputIterator> 
  boost::disable_if< typename is_convertible< T, OutputIterator >::type, size_type >::type 
  pop(OutputIterator it);

Pops objects to the output iterator it

Note

  • Thread-safe and wait-free

Requires:

  • only one thread is allowed to pop data to the spsc_queue

Returns:

number of popped items

Oops. You're invoking UB there as it will assign to &value+1 etc. This was indeed causing std::vector::assign to cry loudly.



标签: c++ boost