zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Vue 路由的编程式导航与history模式
    Vue 路由配置、动态路由
    Vue 组件传值
    Vue 组件以及生命周期函数
    Vue 封装js
    记一次proc_open没有开启心得感悟
    面向内容的标记语言--markdonw
    浅谈索引
    mysql主从配置
    centos7下操作防火墙
  • 原文地址:https://www.cnblogs.com/dream397/p/15094996.html
Copyright © 2011-2022 走看看