问题
I'm trying to put std::string
s into boost::lockfree::queue
s 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