DigestCPP

Lets Understand With Example

  • Home
  • Design Patterns
  • Adapter Design Pattern
  • Strategy Design Pattern
  • C++11 Features
  • std::thread c++11
  • Contact Us

std::mutex with unique lock and lock guard c++11

Mutex(mutual exclusion): It provides the concurrent access to resource.

In c++ 11, We will not use it (mutex) directly (I mean we can use but we have better option of RAII principal (If exception happens after acquiring the mutex then it will be released in destruction otherwise it would have locked forever)), it will be used through two classes:

  1. std::lock_guard
  2. std::unique_lock

Difference between unique lock and lock guard (unique lock vs lock guard) : TODO

std:lock_guard: It is scoped lock, It will get the mutex in constructor and release the mutex after completion of scope(block) in destructor. It has only three API:

  • lock_guard obj1(m)    //create object to lock the mutex.
  • lock_guard obj2(m, adopt_lock)    //create object to lock the already locked mutex.
  • ~lock_guard()    //release the mutex.

std::unique_lock: It is the superior version of lock guard, It has same API of lock_guard and additional API like lock, unlock and try lock etc. so that we can control the mutex from externally.

  • unique_lock obj1(m)    //create object to lock the mutex as like above
  • unique_lock obj2(m, adopt_lock)   //create object to lock the already locked mutex
  • ~unique_lock()          //release the mutex
  • obj1.lock()    //Additional API to lock the mutex, it blocking call
  • obj1.unlock()    //Additional API to unlock the mutex
  • try_lock()    //Additional API to lock the mutex and return immediately with either true or false
  • try_lock_for() //Additional API to lock the mutex and return after given duration with either true or false.

Source code of lock guard with example:

/*
Program: Mutex with Lock Guard 
Author: Alpha Master
Date: 7 Feb 2021
*/

//Header File
#include<iostream>
#include<thread>
#include<chrono>
#include<mutex>

//Global Variable
std::mutex gMtx;

//Print Thread
void PrintThread(std::string str)
{
        {
            std::lock_guard<std::mutex> lg(gMtx);
            //purposefully waiting to verify the result
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout<<"Value: ";
            for(auto i : str)
            {
                std::cout<<i;
            }
            std::cout<<std::endl;
        }
}

int main()
{
    std::cout<<"Mutex with Lock Guard"<<std::endl;
	
    //Thread 1 and its joinable
    std::thread t1(PrintThread, "please print this");
   
    //Thread 2 and its also joinable
    std::thread t2(PrintThread, "This should be printed");

    //std::cout<<"Main thread is Waiting for Child thread"<<std::endl;
    t1.join();
    t2.join();

    return 0;
};

Output WITHOUT mutex:

Mutex with Lock Guard
Value: Value: Tphliease psr isnt thihsould b
e printed

Output with mutex:

Mutex with Lock Guard
Value: please print this
Value: This should be printed

Source code of unique lock with example:

/*
Program: Mutex with Unique Lock 
Author: Alpha Master
Date: 7 Feb 2021
*/

//Header File
#include<iostream>
#include<thread>
#include<chrono>
#include<mutex>

//Global Variable
std::mutex gMtx;

//Print Thread
void PrintThread(std::string str)
{
        {
            std::unique_lock<std::mutex> lg(gMtx);
            //purposefully waiting to verify the result
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout<<"Value: ";
            for(auto i : str)
            {
                std::cout<<i;
            }
            std::cout<<std::endl;
            if(lg)
            {
               lg.unlock();
               std::cout<<"Mutex status: "<<lg.owns_lock()<<std::endl;
               //lock the mutex again, will release in destructor
               lg.lock();
               std::cout<<"Mutex status: "<<lg.owns_lock()<<std::endl;
            }
        }
}

int main()
{
    std::cout<<"Mutex with Lock Guard"<<std::endl;
	
    //Thread 1 and its joinable
    std::thread t1(PrintThread, "please print this");
   
    //Thread 2 and its also joinable
    std::thread t2(PrintThread, "This should be printed");

    //std::cout<<"Main thread is Waiting for Child thread"<<std::endl;
    t1.join();
    t2.join();

    return 0;
};

Output:

Mutex with Lock Guard
Value: This should be printed
Mutex status: 0
Mutex status: 1
Value: please print this
Mutex status: 0
Mutex status: 1

Primary Sidebar

Copyright © 2021

  • Contact us