C++ 동시 멀티스레딩 - std::recursive_mutex 및 std::timed_mutex 사용

1--std::recursive_mutex 사용

        std::recursive_mutex는 재귀적 배타적 뮤텍스를 생성하여 스레드가 이를 여러 번 잠그고 잠금 해제할 수 있도록 합니다.

#include <iostream>
#include <thread>
#include <list>
#include <mutex> // 引入互斥
 
class myClass{
public:
    // 收集数据到消息队列
    void inMsgRecvQueue(){
        for(int i = 0; i < 100; i++){
            // 模拟收集消息
            std::cout << "Running inMsgRecvQueue(), insert one value: " 
                << i << std::endl; 
            // 多次加锁和解锁
            my_mutex.lock();
            my_mutex.lock();
            msgRecvqueue.push_back(i); // 消息队列存储消息
            my_mutex.unlock();
            my_mutex.unlock();
        }
    }
    // 从消息队列取数据
    void outMsgRecvQueue(){
        for(int i = 0; i < 100; i++){
            if(!msgRecvqueue.empty()){
                // 多次加锁和解锁
                my_mutex.lock(); // 加锁
                my_mutex.lock(); // 加锁
                int command = msgRecvqueue.front();
                msgRecvqueue.pop_front(); 
                my_mutex.unlock(); // 解锁
                my_mutex.unlock(); // 解锁
            }
            
            else{
                std::cout << "Running outMsgRecvQueue(), " 
                    "the msgRecvqueue is empty" << std::endl;
            }
        }
    }
private:
    std::list<int> msgRecvqueue; // 消息队列
    std::recursive_mutex my_mutex; // 创建互斥量 
};
 
int main(int argc, char *argv[]){
    // std::recursive_mutex 创建递归的独占互斥量,允许一个线程对其多次加锁和解锁

    myClass sample1;
    std::thread myInMsgObj(&myClass::inMsgRecvQueue, &sample1); // 收集数据线程
    std::thread myOutMsgObj(&myClass::outMsgRecvQueue, &sample1); // 取出数据线程
    myInMsgObj.join();
    myOutMsgObj.join();
    return 0;
}

2--std::timed_mutex 사용

        std::timed_mutex는 시간 제한 기능이 있는 배타적 뮤텍스입니다. try_lock_for()는 잠금을 획득하려고 일정 시간 동안 기다립니다. 잠금을 획득할 수 없는 경우 스레드는 계속 실행됩니다(중요 섹션의 내용 건너뛰기). ; try_lock_until() 은 특정 시점까지 항상 잠금을 획득하려고 시도하지만 지정된 시점 이후에 잠금을 획득할 수 없는 경우 스레드는 계속 실행됩니다(중요 섹션의 내용 건너뛰기).

#include <iostream>
#include <thread>
#include <list>
#include <mutex> // 引入互斥
 
class myClass{
public:
    // 收集数据到消息队列
    void inMsgRecvQueue(){
        for(int i = 0; i < 100; i++){
            std::chrono::seconds timeout(1);
            if(my_mutex.try_lock_for(timeout)){ // 等待1s来获取锁
            // if(my_mutex.try_lock_until(std::chrono::steady_clock::now() + timeout)){
                // 模拟收集消息
                std::cout << "Running inMsgRecvQueue(), insert one value: " 
                    << i << std::endl; 
                msgRecvqueue.push_back(i); // 消息队列存储消息
                my_mutex.unlock();
            }
            else{ // 获取不成功
                std::chrono::seconds sleeptime(1); // 线程休息1s
                std::this_thread::sleep_for(sleeptime);
                std::cout << "can not get the lock" << std::endl;
            }
        }
    }
    // 从消息队列取数据
    void outMsgRecvQueue(){
        for(int i = 0; i < 100; i++){
            if(!msgRecvqueue.empty()){
                my_mutex.lock(); // 加锁
                std::chrono::seconds sleeptime(3);
                std::this_thread::sleep_for(sleeptime);
                int command = msgRecvqueue.front();
                msgRecvqueue.pop_front(); 
                my_mutex.unlock(); // 解锁

            }
            else{
                std::cout << "Running outMsgRecvQueue(), " 
                    "the msgRecvqueue is empty" << std::endl;
            }
        }
    }
private:
    std::list<int> msgRecvqueue; // 消息队列
    std::timed_mutex my_mutex; // 创建互斥量 
};
 
int main(int argc, char *argv[]){
    // std::timed_mutex 带有超时功能的独占互斥量
    myClass sample1;
    std::thread myInMsgObj(&myClass::inMsgRecvQueue, &sample1); // 收集数据线程
    std::thread myOutMsgObj(&myClass::outMsgRecvQueue, &sample1); // 取出数据线程
    myInMsgObj.join();
    myOutMsgObj.join();
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43863869/article/details/132407016