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