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

岁酱吖の 提交于 2019-12-18 07:37:11

问题


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.


回答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.




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




回答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.



来源:https://stackoverflow.com/questions/17452491/how-to-put-stdstring-into-boostlockfreequeue-or-alternative

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!