其他各种mutex互斥量

一、std::recursive_mutex 递归的独占互斥量

1.std::mutex : 独占互斥量,自己lock了,别人就不能lock了。

2.std::recursive_mutex 递归的独占互斥量 : 允许同一个线程,同一个互斥量多次被 lock(),效率上比 mutex 要差一点。如果用到了std::recursive_mutex ,就要考虑代码是否有优化空间。递归次数据说有限制,递归次数太多可能会报异常。

二、带超时的互斥量 std::timed_mutex 和 std::recursive_timed_mutex

 std::timed_mutex 带超时功能的独占互斥量,除了原来mutex 的函数之外,还提供了新的接口。

 try_lock_for() : 就是等待一段时间。如果我拿到了锁,或者等待超过时间没有拿到锁,流程走下来。

 
#include <iostream>
#include <thread>
#include <vector>
#include <list>
#include <mutex>
#include <chrono>
 
using namespace std;
 
class A
{
    public:
        void inMsgRecvQueue()
        {
            for(int i=0;i<100000;i++){
                cout<<"inMsgRecvQueue() begin,insert a element:"<< i<<endl;
                std::chrono::milliseconds timeout(100);
                if(m_timedLock.try_lock_for(timeout))
                {
                    msgRecvQueue.push_back(i);
                    m_timedLock.unlock();
                }
                else
                {
                    cout<<"can not hold the mutex"<<endl;
                    std::chrono::milliseconds sleeptime(100);
                    std::this_thread::sleep_for(sleeptime);
                }
            }
        }
 
        void outMsgRecvQueue()
        {
            for(int i=0;i<10000;i++)
            {
                if(!msgRecvQueue.empty())
                {
                    m_timedLock.lock();

                    //std::chrono::seconds seconds(5);
                    //std::this_thread::sleep_for(seconds);  for test ==> cout<<"can not hold the mutex"<<endl;

                    int command = msgRecvQueue.front();
                    msgRecvQueue.pop_front();
                    m_timedLock.unlock();

                    cout<<"outMsgRecvQueue() is pop a element:"<<i<<endl;
                }
                else
                {
                    cout<<"outMsgRecvQueue() is empty:"<<i<<endl;
                }
            }
        }
 
    private:
        list<int> msgRecvQueue; 
        std::timed_mutex m_timedLock;
};
 
 
int main(){
 
    A myobja;
    thread myOutMsgObj(&A::outMsgRecvQueue,&myobja);
    thread myInMsgObj(&A::inMsgRecvQueue,&myobja);
 
    myOutMsgObj.join();
    myInMsgObj.join();
 
 
    return 0;
}

try_lock_until() : 参数是一个未来的时间点,在这个未来的时间没到的时间内,如果拿到了锁,那么就走下来。如果时间到了,没有拿到锁,程序也走下来。

 
#include <iostream>
#include <thread>
#include <vector>
#include <list>
#include <mutex>
#include <chrono>
 
using namespace std;
 
class A
{
    public:
        void inMsgRecvQueue()
        {
            for(int i=0;i<100000;i++){
                cout<<"inMsgRecvQueue() begin,insert a element:"<< i<<endl;
                std::chrono::milliseconds timeout(100);
                //if(m_timedLock.try_lock_for(timeout))
                if(m_timedLock.try_lock_until(std::chrono::steady_clock::now()+timeout)) 
                {
                    msgRecvQueue.push_back(i);
                    m_timedLock.unlock();
                }
                else
                {
                    cout<<"can not hold the mutex"<<endl;
                    std::chrono::milliseconds sleeptime(100);
                    std::this_thread::sleep_for(sleeptime);
                }
            }
        }
 
        void outMsgRecvQueue()
        {
            for(int i=0;i<10000;i++)
            {
                if(!msgRecvQueue.empty())
                {
                    m_timedLock.lock();

                    //std::chrono::seconds seconds(5);
                    //std::this_thread::sleep_for(seconds);  for test ==> cout<<"can not hold the mutex"<<endl;

                    int command = msgRecvQueue.front();
                    msgRecvQueue.pop_front();
                    m_timedLock.unlock();

                    cout<<"outMsgRecvQueue() is pop a element:"<<i<<endl;
                }
                else
                {
                    cout<<"outMsgRecvQueue() is empty:"<<i<<endl;
                }
            }
        }
 
    private:
        list<int> msgRecvQueue; 
        std::timed_mutex m_timedLock;
};
 
 
int main(){
 
    A myobja;
    thread myOutMsgObj(&A::outMsgRecvQueue,&myobja);
    thread myInMsgObj(&A::inMsgRecvQueue,&myobja);
 
    myOutMsgObj.join();
    myInMsgObj.join();
 
 
    return 0;
}

std::recursive_timed_mutex :带超时功能的递归独占互斥量,允许同一个线程多次获取这个互斥量。

posted @ 2022-12-15 20:49  repinkply  阅读(114)  评论(0)    收藏  举报