Subprocesos múltiples concurrentes en C++: uso de std::recursive_mutex y std::timed_mutex

1--Uso de std::recursive_mutex

        std::recursive_mutex crea un mutex exclusivo recursivo, permitiendo que un hilo lo bloquee y desbloquee varias veces;

#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--Uso de std::timed_mutex

        std::timed_mutex es un mutex exclusivo con una función de tiempo de espera, try_lock_for() espera un período de tiempo para intentar adquirir el bloqueo, si el bloqueo no se puede adquirir, el hilo continúa ejecutándose (omita el contenido de la sección crítica) ; try_lock_until() es hasta cierto punto Intenta adquirir el bloqueo todo el tiempo, si el bloqueo no se puede adquirir más allá del punto de tiempo especificado, el hilo continuará ejecutándose (omita el contenido de la sección crítica);

#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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43863869/article/details/132407016
Recomendado
Clasificación