I'm having some trouble getting my head around Boost mutexes and how
they work.
Basically I have a handful of objects, and they all use a shared
resource (a C-style function.) The function isn't thread-safe, so I
want to protect it to ensure only one thread at a time can call it.
My idea was to create a mutex for this (lock before the call, unlock
after it), but I'm having trouble working out how to share the mutex
between all the objects. The boost::mutex object seems like what I
want, but it's non-copyable so I can't share it among multiple objects.
I tried passing around references to the mutex instead, but this just
triggers an assertion failure when I try to lock it.
Should I be using boost::mutex for this? How would you normally
serialise access among different objects like this? I'm finding the
examples somewhat tricky to work from, as most of them use global
variables and C-style functions for creating threads, which doesn't
really fit with the C++ model of my program - I could just make the
mutex a global variable but it doesn't seem like the cleanest solution
to me.
Any pointers would be much appreciated.
Thanks,
Adam.
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Oh my bad, I just realised the function I'm trying to protect was
failing, causing the main code to terminate early...which of course
resulted in the mutex being destroyed, while the threads were still
using it...
It looks like it all works fine passing around references to the same
boost::mutex object.
Sorry for the noise!
Cheers,
> Basically I have a handful of objects, and they all use a shared
> resource (a C-style function.) The function isn't thread-safe, so I
> want to protect it to ensure only one thread at a time can call it.
>
> My idea was to create a mutex for this (lock before the call, unlock
> after it)...
> I tried passing around references to the mutex ...
>
> Should I be using boost::mutex for this? How would you normally
> serialise access among different objects like this? I'm finding the
> examples somewhat tricky to work from, as most of them use global
> variables and C-style functions for creating threads, which doesn't
> really fit with the C++ model of my program - I could just make the
> mutex a global variable but it doesn't seem like the cleanest solution
> to me.
I think I'd probably create a class to manage access to the shared
function. The class would contain the mutex, and the method that calls
the C function would instantiate the lock object. Nobody else would
directly call the C function any more.
That approach generalizes to a family of related functions, plus
whatever persistent data they might need.
There are a couple of different ways to instantiate the wrapper class.
One is to use the Singleton pattern. Note that Boost accepted a
Singleton library a couple months ago, which hasn't yet made it into an
official Boost release; check the vault for the current version.
Singleton is essentially a global with a bit of protection. But that
might be an acceptable way to manage a global resource (your C function).
Since you already have a way to pass mutex references to your handful of
objects, though, you could pass a reference to your wrapper object
instead. But then you have to figure out where the shared wrapper object
lives, and who's responsible for its lifespan.
I'd probably allocate it on the heap, pointing to it with a
boost::shared_ptr. Store a copy of that boost::shared_ptr in each of
your handful of objects. Ownership is shared among them, and the last
one to leave turns out the lights.
I ended up reaching the same conclusion here, as I wanted to store other
persistent data too (in this case a counter for the number of times the
function was called) and wrapping it all up in a class does make it
cleaner, as you suggest.
> Since you already have a way to pass mutex references to your handful of
> objects, though, you could pass a reference to your wrapper object
> instead.
Yes, I think I prefer this method, as I would rather choose to only have
one instance of the class floating around, as opposed to using a
Singleton pattern with its additional complexity to enforce this rule.
(I'd never heard of the Singleton pattern before - interesting!)
> I'd probably allocate it on the heap, pointing to it with a
> boost::shared_ptr. Store a copy of that boost::shared_ptr in each of
> your handful of objects. Ownership is shared among them, and the last
> one to leave turns out the lights.
I agree - however this time it will be around for the life of the
(fairly simplistic) program, so it'll be just as easy to create it as a
local variable in main(), wait for the threads to terminate and then
have it destroyed automatically.
Thanks for your reply!
Cheers,
Adam.