0

I am studying (refreshing) C++ now. As part of refreshing, I tried to check std::mutex behavior by me below code. It basically trys to do 'Manual lock/unlock', 'std::lock_guard over mutex' and 'try_lock over std::mutex'. When I refer std::mutex::try_lock, it says if same thread tries to lock again, it is a dead-lock. But I am checking try_lock(), which as per above link description, it should give false. But somehow, std::mutex able to lock already locked mutex. I tried googling/stackoverflow, not able to find cause of this behavior. Could you let me know, why std::mutex able to lock again after locking in same thread?

Code:

#include <iostream>
#include <mutex>

template <typename BASICLOCKABLE>
void ManualLockUnlock(BASICLOCKABLE & mut, std::string msg)
{
    mut.lock();
    std::cout << msg << "Manually locked, unlocked\n";

    if(mut.try_lock())
    {
        std::cout << msg << "able to try_lock after manual lock\n";
        mut.unlock();
    }
    else
    {
        std::cout << msg << "UNABLE to try_lock after manual lock\n";
    }
    mut.unlock();
    std::cout << std::endl;
}

template <typename BASICLOCKABLE>
void lock_guard(BASICLOCKABLE & mut, std::string msg)
{
    std::lock_guard<BASICLOCKABLE> lc(mut);
    std::cout << msg << "lock_guard locked, unlocked\n";

    if(mut.try_lock())
    {
        std::cout << msg << "able to try_lock again inside lock_guard\n";
        mut.unlock();
    }
    else
    {
        std::cout << msg << "UNABLE to try_lock again inside lock_guard\n";
    }
    {
        std::lock_guard<BASICLOCKABLE> lc2(mut);
        std::cout << msg << "SECOND LEVEL lock_guard locked, unlocked\n";
    }
    std::cout << std::endl;
}

template <typename BASICLOCKABLE>
void try_lock(BASICLOCKABLE & mut, std::string msg)
{
    mut.try_lock();
    std::cout << msg << "try_lock locked, unlocked\n";

    if(mut.try_lock())
    {
        std::cout << msg << "able to try_lock again inside try_lock\n";
        mut.unlock();
    }
    else
    {
        std::cout << msg << "UNABLE to try_lock again inside try_lock\n";
    }

    mut.unlock();
    std::cout << std::endl;
}

int main()
{
    std::string msg;

    std::mutex mut;
    msg = "std::mutex ";
    ManualLockUnlock(mut, msg);
    lock_guard(mut, msg);
    try_lock(mut, msg);

    std::recursive_mutex    recMut;
    msg = "std::recursive_mutex ";

    ManualLockUnlock(recMut, msg);
    lock_guard(recMut, msg);
    try_lock(recMut, msg);
}

Compile command:

g++ lock_guard.cpp -std=c++11

Output:

std::mutex Manually locked, unlocked
std::mutex able to try_lock after manual lock

std::mutex lock_guard locked, unlocked
std::mutex able to try_lock again inside lock_guard
std::mutex SECOND LEVEL lock_guard locked, unlocked

std::mutex try_lock locked, unlocked
std::mutex able to try_lock again inside try_lock

std::recursive_mutex Manually locked, unlocked
std::recursive_mutex able to try_lock after manual lock

std::recursive_mutex lock_guard locked, unlocked
std::recursive_mutex able to try_lock again inside lock_guard
std::recursive_mutex SECOND LEVEL lock_guard locked, unlocked

std::recursive_mutex try_lock locked, unlocked
std::recursive_mutex able to try_lock again inside try_lock

Compiler that I am using:

g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Tim Diekmann
  • 7,755
  • 11
  • 41
  • 69
gymk
  • 1
  • 2
  • 1
    [If try_lock is called by a thread that already owns the mutex, the behavior is undefined](https://en.cppreference.com/w/cpp/thread/mutex/try_lock) – Killzone Kid Jul 25 '18 at 05:41
  • Thanks for the quick reply Killzone Kid. Could you kindly suggest which site will be concrete to refer for these kind of standard behaviours? Shall I refer https://en.cppreference.com? – gymk Jul 25 '18 at 07:00
  • https://en.cppreference.com/w/cpp/thread/mutex: "A calling thread must not own the mutex prior to calling lock or try_lock." – Kaveh Vahedipour Jul 26 '18 at 13:01

0 Answers0