Question

I have a situation where I'd like to do something like that shown below, but there doesn't seem to be a way of querying the mutex without changing its state. I don't want the someFunctionCalledRepeatedlyFromAnotherThread() to hang around waiting for the mutex to free up if it is locked. It must return immediately after performing some alternative action. I'm guessing this omission is there for safety, as the lock may free up in the time between querying it and the function returning. In my case, bad stuff will not happen if the lock is freed while doSomeAlternativeAction() is happening. The fact I'm in this situation probably means I'm doing something wrong, so how should I change my design?

class MyClass 
{
    std::mutex initMutex;
public:
    void someInitializationFunction()
    {
        std::lock_guard<std::mutex> lock(initMutex);
        // Do some work
    }

    void someFunctionCalledRepeatedlyFromAnotherThread()
    {
        if (initMutex.isLocked()) 
        {
            doSomeAlternativeAction();
            return;
        }
        // otherwise . . .
        std::lock_guard<std::mutex> lock(initMutex);
        // carry on with work as usual
    }
}
Was it helpful?

Solution

Asking mutex for its state is useless: it may be unlocked now, but by the time you get around to lock it, it may be locked. So it does not have such method.

It does, however, have a method try_lock() which locks it if it is not locked and returns true if it acquired the lock and false otherwise. And std::unique_lock (the more advanced version of std::lock_guard) has option to call it.

So you can do:

void someFunctionCalledRepeatedlyFromAnotherThread()
{
    std::unique_lock<std::mutex> lock(initMutex, std::try_to_lock);
    if(!lock.owns_lock())
    {
        doSomeAlternativeAction();
        return;
    }
    // otherwise ... go ahead, you have the lock
}

OTHER TIPS

Sounds like you want to use std::unique_lock instead of std::lock_guard. The try_lock method works similar to the TryEnterCriticalSection on Windows, whereby the function will atomically acquire the lock and return 'true' if it can, or just return 'false' if the lock cannot be acquired (and will not block). Refer to http://msdn.microsoft.com/en-us/library/hh921439.aspx and http://en.cppreference.com/w/cpp/thread/unique_lock/try_lock. Note that unique_lock also has other members available for trying to lock such as try_lock_for and try_lock_until.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top