if any exception occurs in critical section code then what sort of issue which we see in terms of synchronization objects?
Before and after the critical section code, Mutex is locked and unlocked. But if any exception occurs then the waiting thread will be waiting for resource to be freed as Mutex is not unlocked due to the execption.
So what needs to be done to get rid of this issue?
I got your point. But could you please explain with the help of any example code.
One more thing
as we know during stack unwinding destructors gets called for objects created on stack from try block till the place exception thrown. What happens to the memory created on heap. I think there would be a memory leak if not used smart pointer. Am I right? If I see the code below then during stack unwinding destructor would be called for x but not for y, right?
foo()
{
classA x;
classB *y = new classB()
}
I got your point. But could you please explain with the help of any example code.
With C++11 threads, there are 2 classes of interest. std::mutex and std::lock_guard.
std::mutex is the actual mutex with lock() and unlock() functionality. However you probably should never call those routines directly. Instead, you use std::lock_guard, which is a RAII interface for locking/unlocking the mutex.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
std::mutex mymutex;
void bad_example()
{
mymutex.lock();
doStuff(); // BAD, if doStuff throws an exception, mymutex will not unlock!
// potential for program deadlock
mymutex.unlock();
}
void good_example()
{
std::lock_guard lk( mymutex ); // lock_guard's ctor locks the mutex
doStuff();
} // <- lock_guard's dtor unlocks the mutex
The good example is good because no matter what doStuff does (even if it throws an exception), it is guaranteed that lk's destructor will be called, unlocking the mutex.
If I see the code below then during stack unwinding destructor would be called for x but not for y, right?
That is correct. Which, again, is why you RAII with smart pointers.
1 2 3 4 5 6
void foo()
{
classA x;
std::unique_ptr<classB> y( new classB() ); // RAII inside a unique_ptr
} // <- y's dtor will delete the pointer automatically.
Many thanks to explain with example.
But as I asked earlier in meantioned code below
foo()
{
classA x;
classB *y = new classB()
}
If exception is thrown while object is getting created for classB, would still there be a memory leak when
1) some of the memebrs are initialised but not all
2) all members are initialized but because of some other thing exception is thrown