user2601350
user2601350

Reputation: 239

How to solve unreleased lock issue in C++

Someone please help me solve deadlock issues in c++ if possible with reference or examples.

Scenario would be like below.

Thread1 is locked by mutex and doing some operation, thread2 and thread3 are in waiting state for thread1 to unlock to access the resource.

Some abort/unexpected thing happened -- thread1 was terminated and didn't get the unlock, thread2 and thread3 are still waiting.

How to save the main thread (mean nothing should happen to main thread) in such situations.

Please throw some light how to solve such issues in c++.

Thanks, Sheik

Upvotes: 2

Views: 977

Answers (3)

Lior Kogan
Lior Kogan

Reputation: 20618

Generally threads should not terminate unexpectedly. You may try using try/catch blocks. If you still want to free resources when a thread terminates unexpectedly, you may create a monitor thread that waits for the termination of the first thread.

On Windows, you can use something as ::WaitForSingleObject(m_htThread, INFINITE).

Once the 1st thread had been terminated, you may proceed with freeing abandoned locks. Maybe you'll want to add some flag which indicates if the termination was graceful. You'll probably also have to remember which thread is locking which object.

As said, I wouldn't recommend using such method, but on extreme cases.

Upvotes: 2

user207421
user207421

Reputation: 310913

The way to solve deadlocks in any language or platform is always the same.

Always acquire the locks in the same order.

EDIT: However you have misdescribed your problem. This is not a deadlock. A deadlock is a circular chain of locks. This is simply an unreleased lock, i.e. a lock leak. The solution is the same as any other resource leak: don't. In C++ that means releasing resources in destructors, and ensuring that destructors are called. Somehow your thread has terminated without doing that. Find that problem and fix it.

Upvotes: -1

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

Some abort/unexpected thing happened

Use s.th. like std::lock_guard to prevent 'hanging' locks due to exceptions or forgotten/unexpected, but necessary unlock() operations.

The principle is pretty simple and you can easily implement it for any mechanism that uses a pair of methods that correspond together in a 'lock/unlock' manner:

class LockObject // E.g. mutex or alike
{
public:
    // ...
    void lock();
    void unlock();
};

Bind the guard classes constructor to a reference to the lock object's instance and call lock() in the constructor and unlock() in the destructor:

template<typename T>
class LockGuard
{
public:
    LockGuard(T& lockObject)
    : lockObject_(lockObject) 
    {
        lockObject_.lock();
    }
    ~LockGuard()
    {
        lockObject_.unlock();
    }

private:
    T& lockObject_;
};

Use LockGuard like this:

// Some scope providing 'LockObject lockObject'
{ LockGuard<LockObject> lock(lockObject)
    // Do s.th. when lockObject is locked
} // Call of lockObject.unlock() is guaranteed at least here, no matter what
  // (exception, goto, break, etc.) caused leaving the block's scope.

Upvotes: 5

Related Questions