10

I have a strange error.

class INST
{
public:
boost::mutex m_mutex;
};

std::vector<INST> m_inst;

error C2248: 'boost::mutex::mutex' : cannot access private member declared in class 'boost::mutex' see declaration of 'boost::mutex::mutex'

However, my other class is fine,

class VIEW
{
public:
boost::mutex m_mutex;
};

VIEW m_view;

Am I missing something here? I have tried to declare m_mutex to private, but still have the same problem.

Thanks.

2607
  • 4,037
  • 13
  • 49
  • 64
  • C++ errors are usually complex and verbose. Make sure that you copy the full error message (might be multiple error XXX: lines) as each line will add a bit of information to the puzzle (in this case, probably the fact that it is the copy constructor that is not available or that it found the error while defining the copy constructor – David Rodríguez - dribeas Feb 14 '12 at 21:33
  • Thank you David, I am a newbie to multi-thread programming, could you please suggest a solution for the problem? I have a shared vector, and several threads may access different part of the vector at the same time. – 2607 Feb 14 '12 at 21:37

2 Answers2

18

mutexes can't be copied, so you can't place them in a container which would copy the mutex. The error is likely referring to the private copy constructor of the mutex.

nos
  • 223,662
  • 58
  • 417
  • 506
  • Thank you nos, can you please suggest a solution for the problem? I have a shared vector, and several threads may access different part of the vector at the same time. – 2607 Feb 14 '12 at 21:32
  • Place (smart) pointers for the mutex or the class containing the mutex in the container instead. Or protect the entire vector with one mutex. (Or use an array if its appropriate for your task) – nos Feb 14 '12 at 21:38
  • Please correct me if I am wrong, if I use a global mutex to protect the entire vector, does it mean only one thread can access the entire vector at a time? I am trying to allow multiple threads to access different part of the vector at the same time. Thank you. – 2607 Feb 14 '12 at 21:43
  • @2607: It all depends on the problem that you want to solve and how you mean to solve it. First solution that comes to mind is providing a copy constructor (and assignment operator) that does not try to copy the mutex (the mutex is not part of the object, but rather an auxiliary tool to handle thread safety --btw, it should probably be `mutable`). – David Rodríguez - dribeas Feb 14 '12 at 21:43
  • 1
    @nos: If you use a shared pointer for the mutex you are opening the code to unwanted side effects, as `object a; object b(a);` --> now both `a` and `b` *share* the single mutex, which is probably unwanted. – David Rodríguez - dribeas Feb 14 '12 at 21:44
  • @nos: I recommend that you pick up *C++ Concurrency in action* by Anthony Williams. It is quite an interesting read and will help you think on the problem as a whole (hint: thread safe access to all members does not imply that the object is thread safe...) – David Rodríguez - dribeas Feb 14 '12 at 21:46
  • @DavidRodríguez-dribeas, if I only pass a reference to the vector, e.g., vector m_inst. In other words, if I create a vector of object pointers, instead of a vector of objects, will that solve the problem? Thanks. – 2607 Feb 14 '12 at 22:05
  • @2607: The *problem* is that you have not *defined* what the problem to solve is. From the point of view of the compiler yes, that is another way of solving the inability to copy, but it comes with the cost of manual memory management of the objects stored in the pointer, where you cannot just assume that once the vector goes out of scope they will be cleared. It is good on the other hand, as it removes the need for *copies* that are usually hard to do correctly (i.e. thread safe and with no locking in a multithreaded environment) Note that you will probably need to also protect the vector. – David Rodríguez - dribeas Feb 14 '12 at 22:56
  • @DavidRodríguez-dribeas, thank you for your reply. I am trying to achieve this. I have a vector of objects, which I would like to share among multiple threads. Each thread may have exclusive access to one vector element at a time, without locking the entire vector. Thanks. – 2607 Feb 15 '12 at 00:38
  • @2607: Comments are not the best form for this, I recommend that you open a new question stating what you really need to do, and be as clear and explicit as possible. Even if your last comment seems self explanatory to you, it might not be for others. Does that mean that each thread will only work on a single element of the vector? Or that they can operate on all elements but access to each one must be protected? Can the vector be modified (elements added/removed) while there are threads working on the elements? Even if none of the added/removed elements is currently being used? – David Rodríguez - dribeas Feb 15 '12 at 13:03
2

I realize that this question is really old, but I stumbled upon the same problem earlier today and Google lead me here. However, the proposed solution did not suit me so I wanted to describe how I solved it in my own project.

I have a vector of classes just like you, and I manage these in such a way so that once access to the members of the vector begins, the vector will never be resized again. I do want the ability to resize the vector a few times at the start, though, before processing begins. I also wanted to allow the threads to operate on any of the items in the vector in a random access fashion.

I solved the problem with the mutex by allocating it dynamically in the constructor of the class, and destroying it in the destructor. Naturally, if you do this you must guarantee that nobody is waiting on the mutex when you delete it. This solution works for me because I never copy objects out of the vector, I only access them inside of the container.

Philip Bennefall
  • 1,477
  • 5
  • 20
  • 33