copying mutexes, cv and pthread_ts

D

drawoh

Hi All,

I have a class that creates a thread, a mutex and a condition variable
in its constructor. I am writing a copy constructor for this class in
C++. I am doing a simple copy using the member initialization list.
First of all, does anyone have any opinion about whether this will work
fine. I think it will. I believe a copy constructor, when using a
member initialization list, does a memory copy of the object's members
to be copied. In which case I believe this should work.
Does anyone have a different opinion about the feasibility of this? The
reason I am trying to do this copy constructor is to push this class
into a vector container. But I am not sure about what will happen when
I try to erase this element from the vector. I am gonna do the
destructor later, I have the destructor figured out though.

Ciao, Draw
 
M

Marcin 'Qrczak' Kowalczyk

I have a class that creates a thread, a mutex and a condition
variable in its constructor. I am writing a copy constructor
for this class in C++. I am doing a simple copy using the member
initialization list. First of all, does anyone have any opinion
about whether this will work fine.

It will not. Mutexes and conditions are non-copyable.

They may refer to dynamically allocated memory, or they may include
addresses registered with the OS. They are typically implemented in C,
so there is no C++ copy constructor nor assignment operator defined
for them, and thus you will typically get a bitwise copy rather than
an error, which doesn't need to yield a sensible semantics however.

Besides, it's not clear what would it mean to copy them if somebody is
waitng on them, or whether a copy of a locked mutex should be locked.
They are non-copyable conceptually, not only technically.

It's possible that for a class which includes a mutex, a sensible copy
constructor should freshly initialize the mutex in the copy. Possibly
while keeping the mutex of the original locked, to prevent taking the
snapshot of data which is being modified by another thread. This all
depends on the locking policy.

Disclaimer: I've never tried to make a copyable object which includes
a mutex, this is all guessing from my head.
 
I

Ian Collins

Hi All,

I have a class that creates a thread, a mutex and a condition variable
in its constructor. I am writing a copy constructor for this class in
C++. I am doing a simple copy using the member initialization list.
First of all, does anyone have any opinion about whether this will work
fine. I think it will. I believe a copy constructor, when using a
member initialization list, does a memory copy of the object's members
to be copied. In which case I believe this should work.
Does anyone have a different opinion about the feasibility of this? The
reason I am trying to do this copy constructor is to push this class
into a vector container. But I am not sure about what will happen when
I try to erase this element from the vector. I am gonna do the
destructor later, I have the destructor figured out though.
Apart from not being possible, does it make any sense to copy them?

If you require locking on each instance of the class, you have to
initialise a new mutex and cv for each instance. If you require global
locking for all instances of the class, use static members.
 
E

Earl Purple

Apart from not being possible, does it make any sense to copy them?

If you require locking on each instance of the class, you have to
initialise a new mutex and cv for each instance. If you require global
locking for all instances of the class, use static members.

No you don't want static members. Just because you can't copy the class
doesn't mean you can't have more than one instance.

If you want to share this collection aruond then use shared_ptr. (It's
in tr1 and boost). The only worry is that shared_ptr isn't strictly
thread-safe but actually the only issue is in deletion if two threads
decrease the reference count at the same time and then either both or
neither thread invokes the delete. With proper marshalling you can
avoid this problem.
 
I

Ian Collins

Earl said:
No you don't want static members.

Why not?
Just because you can't copy the class doesn't mean you can't have more than one instance.
Isn't that what I said?
If you want to share this collection aruond then use shared_ptr. (It's
in tr1 and boost). The only worry is that shared_ptr isn't strictly
thread-safe but actually the only issue is in deletion if two threads
decrease the reference count at the same time and then either both or
neither thread invokes the delete. With proper marshalling you can
avoid this problem.
What benefit does this offer over a static member?
 
E

Earl Purple

Ian said:

Because a static member is the same for every instance of the class.
Isn't that what I said?

But having a static member means a variable that is shared between
every instance of your class. Do you really want that?
What benefit does this offer over a static member?

shared_ptr simply gives reference counting to pointers. Pointers are
weak-references to the same class. When you copy a shared_ptr you
simply up its reference count so you do not need to handle the memory
management, and when the last reference is destroyed, the class is
deleted, with its destructor called.

The big advantage of C++ is RAII which is basically the automatic use
of destructors.
 
I

Ian Collins

Earl said:
Because a static member is the same for every instance of the class.




But having a static member means a variable that is shared between
every instance of your class. Do you really want that?
If you read my original post, I said "If you require global locking for
all instances of the class, use static members." That is, one mutex
shared by all instances of the class.
shared_ptr simply gives reference counting to pointers. Pointers are
weak-references to the same class. When you copy a shared_ptr you
simply up its reference count so you do not need to handle the memory
management, and when the last reference is destroyed, the class is
deleted, with its destructor called.
So you advocate the used of a non-trivial class member to share a mutex
between all instances of a class over a simple static member?
 
E

Earl Purple

Ian said:
If you read my original post, I said "If you require global locking for
all instances of the class, use static members." That is, one mutex
shared by all instances of the class.

Yes, agreed, you could do it that way, but you would have to be certain
that your design is right and that you really do want to lock every
instance of a class and that such will remain the case forever. Because
once you decide you want other instances of the class not in this
"group" then you have to go back and change a lot of code.

OP was originally going to create a class then attempt to copy it using
copy-constructors etc, which suggested he did not necessarily want just
one instance, but wanted to pass a particular instance around and have
global locking on those particular instances.
So you advocate the used of a non-trivial class member to share a mutex
between all instances of a class over a simple static member?

Whilst shared_ptr is non-trivial to write, you don't have to write it,
boost have already done so. It is relatively trivial to use. The only
issue in a multi-threaded environment is a bit of marshalling to ensure
two threads don't try to delete the last reference at exactly the same
time. That's usually fairly simple to administer with a thread join.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top