Discussion:
[LockFree] a queue of std::shared_ptr?
Scott Smedley
2013-02-12 00:04:04 UTC
Permalink
Hi all,

Is it possible to store std::shared_ptr objects in a boost::lockfree::queue?

eg. boost::lockfree::queue<std::shared_ptr<Message>> q;

gcc 4.7.2 with Boost 1.53.0 is giving a static assertion failure. It
wants: boost::has_trivial_destructor<T>::value and
boost::has_trivial_assign<T>::value

Any help would be muchly appreciated.

Scott.
Michael Caisse
2013-02-12 09:26:37 UTC
Permalink
Post by Scott Smedley
Hi all,
Is it possible to store std::shared_ptr objects in a boost::lockfree::queue?
eg. boost::lockfree::queue<std::shared_ptr<Message>> q;
gcc 4.7.2 with Boost 1.53.0 is giving a static assertion failure. It
wants: boost::has_trivial_destructor<T>::value and
boost::has_trivial_assign<T>::value
Any help would be muchly appreciated.
Scott.
Hi Scott -

Lockfree queues require that the queued type (T) meets the following
requirements:

o T must have a copy constructor
o T must have a trivial assignment operator
o T must have a trivial destructor


shared_ptr has neither a trivial assignment operator or destructor and
cannot be used in the lockfree containers.

michael
--
Michael Caisse
ciere consulting
ciere.com
chris
2013-02-14 18:17:47 UTC
Permalink
Hello All,

If we can't use shared_ptr in a lockfree queue, how can I share data
between different queue ?

I have some data that I have to be put in different queues and I want to
avoid that I have to copy this data for each queue.



--
View this message in context: http://boost.2283326.n4.nabble.com/LockFree-a-queue-of-std-shared-ptr-tp4642662p4642868.html
Sent from the Boost - Users mailing list archive at Nabble.com.
Brian Budge
2013-02-14 20:21:25 UTC
Permalink
Post by chris
Hello All,
If we can't use shared_ptr in a lockfree queue, how can I share data
between different queue ?
I have some data that I have to be put in different queues and I want to
avoid that I have to copy this data for each queue.
1) Use raw pointers with boost lockfree queues
2) Use shared pointers with a std::queue and a boost::mutex to ensure
thread safety (note that this may not necessarily be slower than using
the lockfree queue)
3) Use moveable objects with boost container deque

There are more options, if one of these does not suffice.

Brian
Chris Herssens
2013-02-15 07:53:38 UTC
Permalink
If I define a structure that contains a shared_ptr. Can I put this
structure in a lockfree queue ?
Post by Brian Budge
Post by chris
Hello All,
If we can't use shared_ptr in a lockfree queue, how can I share data
between different queue ?
I have some data that I have to be put in different queues and I want to
avoid that I have to copy this data for each queue.
1) Use raw pointers with boost lockfree queues
2) Use shared pointers with a std::queue and a boost::mutex to ensure
thread safety (note that this may not necessarily be slower than using
the lockfree queue)
3) Use moveable objects with boost container deque
There are more options, if one of these does not suffice.
Brian
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Brian Budge
2013-02-15 14:48:05 UTC
Permalink
Post by Chris Herssens
If I define a structure that contains a shared_ptr. Can I put this
structure in a lockfree queue ?
No. Any struct with nontrivial member is also nontrivial. Here when I say
nontrivial, I mean that it cannot simply be bitwise copied.

Brian

Brian
Johannes Stallkamp
2013-02-15 15:43:42 UTC
Permalink
Hi Chris,
Post by chris
Hello All,
If we can't use shared_ptr in a lockfree queue, how can I share data
between different queue ?
I have some data that I have to be put in different queues and I want to
avoid that I have to copy this data for each queue.
We are in a similar situation concerning the need that the objects are
usually passed along as shared_ptr's but at some point need to be passed
to a worker thread via a lock-free queue.

To solve this problem, we allocate a copy of the shared_ptr on the heap
and pass the raw pointer (to the shared_ptr) into the queue. Of course,
in this case, the receiving worker thread needs to take care of deleting
the heap-allocated shared_ptr.

HTH,
Johannes
Brian Budge
2013-02-15 17:43:22 UTC
Permalink
Post by Johannes Stallkamp
Hi Chris,
Post by chris
Hello All,
If we can't use shared_ptr in a lockfree queue, how can I share data
between different queue ?
I have some data that I have to be put in different queues and I want to
avoid that I have to copy this data for each queue.
We are in a similar situation concerning the need that the objects are
usually passed along as shared_ptr's but at some point need to be passed
to a worker thread via a lock-free queue.
To solve this problem, we allocate a copy of the shared_ptr on the heap
and pass the raw pointer (to the shared_ptr) into the queue. Of course,
in this case, the receiving worker thread needs to take care of deleting
the heap-allocated shared_ptr.
HTH,
Johannes
_______________________________________________
Boost-users mailing list
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Although this is only opinion, if you truly need shared_ptr, it's
probably better to use std::queue and a boost::mutex unless you are
absolutely sure that you require lock free data structures. The
author of the library himself will tell you that it's not always
faster to use the lockfree::queue than to use a std::queue with a
mutex.

Brian
Krzysztof Czainski
2013-02-22 16:14:24 UTC
Permalink
Post by Michael Caisse
Post by Scott Smedley
Hi all,
Is it possible to store std::shared_ptr objects in a
boost::lockfree::queue?
eg. boost::lockfree::queue<std::**shared_ptr<Message>> q;
Hi Scott -
Lockfree queues require that the queued type (T) meets the following
o T must have a copy constructor
o T must have a trivial assignment operator
o T must have a trivial destructor
shared_ptr has neither a trivial assignment operator or destructor and
cannot be used in the lockfree containers.
michael
Hello,

I'm curious: suppose T is a type, that meets requirements for lockfree
queues. Does optional<T> meet those requirements?

a) Does optional<T> have a copy constructor? Yes.
b) Does optional<T> have a trivial assignment operator? Well, the
assignment is user-written in optional, but it's observable effect is
equivalent to memcpy, isn't it?
c) Does optional<T> have a trivial destructor? Well, optional's destructor
conditionally calls T's destructor, which is trivial. So is a destructor
trivial, if all it does is conditionally call a trivial destructor?

Regards,
Kris
Jeffrey Lee Hellrung, Jr.
2013-02-22 17:01:57 UTC
Permalink
Post by Krzysztof Czainski
Post by Michael Caisse
Post by Scott Smedley
Hi all,
Is it possible to store std::shared_ptr objects in a
boost::lockfree::queue?
eg. boost::lockfree::queue<std::**shared_ptr<Message>> q;
Hi Scott -
Lockfree queues require that the queued type (T) meets the following
o T must have a copy constructor
o T must have a trivial assignment operator
o T must have a trivial destructor
shared_ptr has neither a trivial assignment operator or destructor and
cannot be used in the lockfree containers.
michael
Hello,
I'm curious: suppose T is a type, that meets requirements for lockfree
queues. Does optional<T> meet those requirements?
a) Does optional<T> have a copy constructor? Yes.
b) Does optional<T> have a trivial assignment operator? Well, the
assignment is user-written in optional, but it's observable effect is
equivalent to memcpy, isn't it?
c) Does optional<T> have a trivial destructor? Well, optional's destructor
conditionally calls T's destructor, which is trivial. So is a destructor
trivial, if all it does is conditionally call a trivial destructor?
This is true in theory for an optional implementation like boost::optional,
which uses a boolean flag to indicate initialization state, though I'd
doubt all the necessary type traits are specialized for boost::optional.
However, an optional implementation that uses a pointer to indicate
initialization state (null pointer indicates uninitialized, otherwise
pointer points to internal buffer; thus, get_ptr() just returns the
pointer) would not have a trivial copy constructor and assignment operator,
and I think technically, whether boost::optional uses a boolean flag or a
pointer is an implementation detail.

- Jeff
Krzysztof Czainski
2013-02-22 17:19:42 UTC
Permalink
Post by Jeffrey Lee Hellrung, Jr.
Post by Krzysztof Czainski
Post by Michael Caisse
Post by Scott Smedley
Hi all,
Is it possible to store std::shared_ptr objects in a
boost::lockfree::queue?
eg. boost::lockfree::queue<std::**shared_ptr<Message>> q;
Hi Scott -
Lockfree queues require that the queued type (T) meets the following
o T must have a copy constructor
o T must have a trivial assignment operator
o T must have a trivial destructor
shared_ptr has neither a trivial assignment operator or destructor and
cannot be used in the lockfree containers.
michael
Hello,
I'm curious: suppose T is a type, that meets requirements for lockfree
queues. Does optional<T> meet those requirements?
a) Does optional<T> have a copy constructor? Yes.
b) Does optional<T> have a trivial assignment operator? Well, the
assignment is user-written in optional, but it's observable effect is
equivalent to memcpy, isn't it?
c) Does optional<T> have a trivial destructor? Well, optional's
destructor conditionally calls T's destructor, which is trivial. So is a
destructor trivial, if all it does is conditionally call a trivial
destructor?
This is true in theory for an optional implementation like
boost::optional, which uses a boolean flag to indicate initialization
state, though I'd doubt all the necessary type traits are specialized for
boost::optional. However, an optional implementation that uses a pointer to
indicate initialization state (null pointer indicates uninitialized,
otherwise pointer points to internal buffer; thus, get_ptr() just returns
the pointer) would not have a trivial copy constructor and assignment
operator, and I think technically, whether boost::optional uses a boolean
flag or a pointer is an implementation detail.
- Jeff
Ok, that makes sense.

Cheers,
Kris

Loading...