std::lock_guard unique_lock

/*
    *lock_guard C++源码 内容也比较简单
    *私有化了拷贝构造和赋值拷贝
    *在内部对锁和构造和析构进行了适配
*/
template<class _Mutex>
    class lock_guard<_Mutex>
    {    // specialization for a single mutex
public:
    typedef _Mutex mutex_type;

    explicit lock_guard(_Mutex& _Mtx)
        : _MyMutex(_Mtx)
        {    // construct and lock
        _MyMutex.lock();
        }

    lock_guard(_Mutex& _Mtx, adopt_lock_t)
        : _MyMutex(_Mtx)
        {    // construct but don't lock
        }

    ~lock_guard() _NOEXCEPT
        {    // unlock
        _MyMutex.unlock();
        }

    lock_guard(const lock_guard&) = delete;
    lock_guard& operator=(const lock_guard&) = delete;
private:
    _Mutex& _MyMutex;
};
 
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>
#include <chrono>
std::mutex my_lock;

void add(int &num, int &sum){
    std::cout <<"in thread " << std::this_thread::get_id() << std::endl;
    while(true){
        auto beginTime = std::chrono::high_resolution_clock::now();
        std::lock_guard<std::mutex> lock(my_lock);  
        auto endTime = std::chrono::high_resolution_clock::now();
        auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime);
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        std::cout <<std::this_thread::get_id() << " elapsed time is  " << elapsedTime.count() << " second" << std::endl;
        if (num < 10){ //运行条件
            num += 1;
            sum += num;
        }   
        else {  //退出条件
            break;
        }   
    }   
}

int main(){
    int sum = 0;
    int num = 0;
    std::vector<std::thread> ver;   //保存线程的vector
    for(int i = 0; i < 2; ++i){
        std::thread t = std::thread(add, std::ref(num), std::ref(sum));
        ver.emplace_back(std::move(t)); //保存线程
    }   

    std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join
    std::cout << sum << std::endl;
}

root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread

root@ubuntu:~/c++# ./thread1
in thread in thread 281472855114192281472863506896

281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472863506896 elapsed time is  0 second
281472855114192 elapsed time is  11 second
55
281472855114192这个线程花了11秒才获得锁

我们会尝试用mutex的lock()去锁定这个mutex,但如果没有锁定成功,我也会立即返回,并不会阻塞在那里;

用这个try_to_lock的前提是你自己不能先lock。实例代码如下:

 
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>
#include <chrono>
std::mutex my_lock;

void add(int &num, int &sum){
    std::cout <<"in thread " << std::this_thread::get_id() << std::endl;
    while(true){
        auto beginTime = std::chrono::high_resolution_clock::now();
        //std::lock_guard<std::mutex> lock(my_lock);  
        std::unique_lock<std::mutex> sbguard(my_lock, std::try_to_lock);
        auto endTime = std::chrono::high_resolution_clock::now();
        auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime);
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        std::cout <<std::this_thread::get_id() << " elapsed time is  " << elapsedTime.count() << " second" << std::endl;
        if (sbguard.owns_lock())
        {
                if (num < 10){ //运行条件
                num += 1;
                sum += num;
                }   
                else {  //退出条件
                 break;
                }   
        }
        else
        {
                std::cout << std::this_thread::get_id() << " do other "  << std::endl;
        }
    }   
}

int main(){
    int sum = 0;
    int num = 0;
    std::vector<std::thread> ver;   //保存线程的vector
    for(int i = 0; i < 2; ++i){
        std::thread t = std::thread(add, std::ref(num), std::ref(sum));
        ver.emplace_back(std::move(t)); //保存线程
    }   

    std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join
    std::cout << sum << std::endl;
}
root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread
root@ubuntu:~/c++# ./thread1
in thread in thread 281473401266640281473409659344

281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473409659344 elapsed time is  0 second
281473401266640 elapsed time is  0 second
281473401266640 do other 
281473401266640 elapsed time is  0 second
55

std::defer_lock

       这个参数表示暂时先不lock,之后手动去lock,但是使用之前也是不允许去lock。一般用来搭配unique_lock的成员函数去使用。下面就列举defer_lock和一些unique_lock成员函数的使用方法。

       当使用了defer_lock参数时,在创建了unique_lock的对象时就不会自动加锁,那么就需要借助lock这个成员函数来进行手动加锁,当然也有unlock来手动解锁。这个和mutex的lock和unlock使用方法一样,实现代码如下:

#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>
#include <chrono>
std::mutex my_lock;

void add(int &num, int &sum){
    std::cout <<"in thread " << std::this_thread::get_id() << std::endl;
    while(true){
        std::unique_lock<std::mutex> sbguard(my_lock, std::defer_lock);
        auto beginTime = std::chrono::high_resolution_clock::now();
        sbguard.lock();
                num += 1;
        sbguard.unlock();
        auto endTime = std::chrono::high_resolution_clock::now();
        auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime);
        std::cout <<std::this_thread::get_id() << " elapsed time is  " << elapsedTime.count() << " second" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        if(num >= 10)
        {
                break;
        }
    }   
}

int main(){
    int sum = 0;
    int num = 0;
    std::vector<std::thread> ver;   //保存线程的vector
    for(int i = 0; i < 2; ++i){
        std::thread t = std::thread(add, std::ref(num), std::ref(sum));
        ver.emplace_back(std::move(t)); //保存线程
    }   

    std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join
    std::cout << sum << std::endl;
}
root@ubuntu:~/c++# ./thread1
in thread in thread 281473381425616281473373032912

281473373032912 elapsed time is  281473381425616 elapsed time is  00 second second

281473373032912 elapsed time is  0 second
281473381425616 elapsed time is  0 second
281473373032912 elapsed time is  0 second
281473381425616 elapsed time is  0 second
281473373032912 elapsed time is  0 second
281473381425616 elapsed time is  0 second
281473373032912 elapsed time is  0 second
281473381425616 elapsed time is  0 second
0
root@ubuntu:~/c++# cat lock_guard1.cpp
#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>
#include <chrono>
std::mutex my_lock;

void add(int &num, int &sum){
    std::cout <<"in thread " << std::this_thread::get_id() << std::endl;
    while(true){
        std::unique_lock<std::mutex> sbguard(my_lock, std::defer_lock);
        auto beginTime = std::chrono::high_resolution_clock::now();
        sbguard.lock();
        auto endTime = std::chrono::high_resolution_clock::now();
        auto elapsedTime= std::chrono::duration_cast<std::chrono::seconds>(endTime - beginTime);
        std::cout <<std::this_thread::get_id() << " elapsed time is  " << elapsedTime.count() << " second" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(2000));
        num += 1;
        sbguard.unlock();
        //std::this_thread::sleep_for(std::chrono::milliseconds(100));
        if(num >= 10)
        {
                break;
        }
    }   
}

int main(){
    int sum = 0;
    int num = 0;
    std::vector<std::thread> ver;   //保存线程的vector
    for(int i = 0; i < 2; ++i){
        std::thread t = std::thread(add, std::ref(num), std::ref(sum));
        ver.emplace_back(std::move(t)); //保存线程
    }   

    std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join
    std::cout << sum << std::endl;
}
root@ubuntu:~/c++# g++ -std=c++11 lock_guard1.cpp -o thread1 -pthread
root@ubuntu:~/c++# ./thread1
in thread in thread 281473229185488281473237578192

281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473229185488 elapsed time is  0 second
281473237578192 elapsed time is  20 second
0
281473237578192  等了  20 second
原文地址:https://www.cnblogs.com/dream397/p/15094996.html