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
  • 相关阅读:
    HDU2059(龟兔赛跑)
    pat 1012 The Best Rank
    pat 1010 Radix
    pat 1007 Maximum Subsequence Sum
    pat 1005 Sign In and Sign Out
    pat 1005 Spell It Right
    pat 1004 Counting Leaves
    1003 Emergency
    第7章 输入/输出系统
    第六章 总线
  • 原文地址:https://www.cnblogs.com/dream397/p/15094996.html
Copyright © 2011-2022 走看看