I appreciate your advice Mario, but I just wanted to know incase there was a situation where I had to explicitly unlock a mutex. I doubt there is, and i'm sure another method could be devised where this wasnt necessary, but at the same time i'm sure there are situations where a scoped lock could cause some kind of deadlock. The example I am about to give is most likely VERY bad code, especially for multi-threading, but nevertheless demonstrates an example of my point.
You have 2 threads, thread1 and thread2. You also have 2 shared objects, obj1 and obj2. You therefor have 2 mutexes, obj1_mutex and obj2_mutex.
Here is the code for thread one...
Code:
#include "mutexes.h"
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
void someFunction1() {
boost::mutex::scoped_lock lock(obj1_mutex);
change(&obj1);
anotherFunction1();
//more code...
}
void anotherFunction1(){
boost::mutex::scoped_lock lock(obj2_mutex);
change(&obj2);
return;
}
And heres the code for thread2...
Code:
#include "mutexes.h"
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
void someFunction2() {
boost::mutex::scoped_lock lock(obj2_mutex);
change(&obj2);
anotherFunction2();
//more code...
}
void anotherFunction2(){
boost::mutex::scoped_lock lock(obj1_mutex);
change(&obj1);
return;
}
And heres a possible scenario of what may happen at runtime...
-thread1 begins execution.
-thread1 acquires lock for obj1
-thread2 begins exectuion.
-thread2 acquires lock for obj2
-thread1 calls a function which requires a lock on obj2.
-thread2 already has a lock on obj2, so it waits..
-thread2 calls a function which requires a lock on obj1.
-thread1 already has a lock on obj1 (since the lock hasnt gone out of scope yet), so it also waits..
-and waits..
-and waits....
As I said, this is probably extremely bad programming, and I cant think of a real-world example where the above algorithms would be needed. However, as my threaded program becomes more complex, whos to say that I might not code something like that accidently. It could certainly be debugged easily, but the errors are likely to occur at runtime, which would make it tricky to trace the problem. Surely overall it is safer to call the destructor on the lock once the shared resource for which the lock was called has been used. Maybe not, i'm not sure tbh.
You know more on this subject than me, so i'm not saying youre wrong. Just pointing out why I asked the question