how to put std::string into boost::lockfree::queue

2019-02-21 11:08发布

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.

3条回答
我只想做你的唯一
2楼-- · 2019-02-21 11:37

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).

查看更多
一纸荒年 Trace。
3楼-- · 2019-02-21 11:40

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.

查看更多
混吃等死
4楼-- · 2019-02-21 11:55

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.

查看更多
登录 后发表回答