how to put std::string into boost::lockfree::queue (or alternative)?

10,402

Solution 1

If you put raw pointers in the queue, the old std::strings will be leaked, since there is no way to free them when they are no longer needed. This is because there is no way to free the objects in a thread-safe way without taking a lock (other than some tricks like hazard pointers, which boost::lockfree::queue does not use)

For technical reasons I do not really understand, the boost::lockfree::queue requires a trivial assignment operator and a trivial destructor, which means that your object cannot be nor contain any data type that must free memory in its destructor, like std::string.

Solution 2

The boost::lockfree::queue documentation clearly states the the contained itemm must have a trivial copy assignment and destructor, which std::string doesn't have.

If you have a single producer and a single consumer you can use spsc_queue (http://www.boost.org/doc/libs/1_54_0/doc/html/boost/lockfree/spsc_queue.html) which requires only default constructability and copyability.

If you have multiple producers or consumers you're going to be stuck with a normal locking queue (or a custom string that doesn't use dynamic allocation).

Solution 3

I have no hope of ever fixing this myself, as I'm almost brand new to c++.

Then I have to wonder why you're messing with things like lockfree queues.

Is there an alternative way to pass text data between threads with lockfree?

Yes, you could just store a std::string* pointer to the data in the queue, because a pointer is a trivial type and so is allowed in the queue. Equivalently, you could store a reference_wrapper<std::string>. The problem with that is you need to store the strings somewhere else, in order to be able to point to them, so now all you've done is move the problem to somewhere else (e.g. you could maintain a list of strings in each thread, and store pointers to the externally-managed string in the lock-free queue, but you don't know when it's safe to remove a string from the per-thread list so it grows and grows.)

I would suggest you use a simple std::queue<std::string> and do your own synchronisation with a boost::mutex and boost::condition_variable, or find an existing implementation of a thread-safe (not lock-free!) queue.

Share:
10,402
Admin
Author by

Admin

Updated on June 03, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm trying to put std::strings into boost::lockfree::queues so that my threads can update each other with new data.

    When I try to use boost::lockfree::queue<std::string> updated_data;, g++ says :

    In instantiation of 'class boost::lockfree::queue >':

    error: static assertion failed: (boost::has_trivial_destructor::value)

    error: static assertion failed: (boost::has_trivial_assign::value)

    I've been shown generally what these errors mean, but I have no hope of ever fixing this myself, as I'm almost brand new to c++.

    Is there an alternative way to pass text data between threads with lockfree? If not, please show me how to put std::string into a boost::lockfree::queue.