std::lock_guard in C++

Working on a project that I currently have, I’ve found myself needing some mutual exclusion in dealing with some hardware devices. I could have gone the singleton route, where I only keep one device representation in memory at a time, but the internet and stack overflow have both told me how I am oh so wrong for wanting that.

Thinking then about how I can support multiple devices in the future, while maintaining a single-device for now in a thread-safe manner, I’m forced to use mutexes to protect critical sections of code. With this approach, the only global variable that I have is an std::mutex which I use to perform my locking.

So, to deal with that std::mutex, I’ve come across something cool, std::lock_guard. I wanted semantics that would roughly match the following Java code.

try {
    this.lock.lock();
    doThing();
} finally {
    this.lock.unlock();
}

This would cause doThing() to only be executed by one calling thread at a time, with the rest being gated by this.lock.lock(). finally in Java allows us to ensure that a block of code runs no matter what. In this case, we are releasing the lock.

std::lock_guard uses a similar mechanism to ensure that locks are released, but it’s more like Golang’s defer.

When the acquired lock goes out of scope, it is released! In ways, it may even be simpler than defer.

So, with this new knowledge, I was able to write code like this:

    bool Device::is_connected()
    {
        const std::lock_guard<std::mutex> lock( Device::m_device_mutex ); // m_device_mutex is a static variable in Device
        return this->m_device != nullptr;
    }

The lock is acquired by that first line, and it is released by going out of scope. This leads to very clean, concise code. I’ve in effect implemented a singleton too by using the static Device::m_device_mutex along with a std::shared_ptr to my hardware.

 Share!

 
I run WindleWare! Feel free to reach out!

Subscribe for Exclusive Updates

* indicates required