一、lock_guard
lock_guard是一种在作用域内控制可锁对象所有权的类型。
(原文:An object of type lock_guard controls the ownership of a lockable object within a scope. )
lock_guard具有两种构造方法:
lock_guard(mutex& m) lock_guard(mutex& m, adopt_lock)
其中mutex& m 是互斥量,参数adopt_lock 表示假定调用线程已经获得互斥体所有权并对其进行管理了。。
二、使用示例
#include <iostream>
#include <mutex>
#include <vector>
#include <string>
#include <ctime>
#include <thread>
using namespace std;
string mock_msg()
{
char buff[30] = { 0 };
static int i = 100000;
sprintf_s(buff, "%d", i--);
return buff;
}
class CMutexTest
{
public:
void recv_msg();
void read_msg();
private:
vector<string> msg_queue;
mutex m_mutex;
};
void CMutexTest::recv_msg()
{
while (true)
{
string msg = mock_msg();
cout << "recv the msg " << msg << endl;
{
lock_guard<mutex> mylockguard(m_mutex);
msg_queue.push_back(msg);
}
this_thread::sleep_for(chrono::milliseconds(10));
}
}
void CMutexTest::read_msg()
{
while (true)
{
m_mutex.lock();
lock_guard<mutex> mylockguard(m_mutex, adopt_lock);
if (!msg_queue.empty())
{
string msg = msg_queue.front();
cout << "read the msg " << msg << endl;
msg_queue.erase(msg_queue.begin());
}
this_thread::sleep_for(chrono::milliseconds(15));
}
}
int main()
{
CMutexTest my_test;
thread recv_thread(&CMutexTest::recv_msg, &my_test);
thread read_thread(&CMutexTest::read_msg, &my_test);
recv_thread.join();
read_thread.join();
}
三、原理分析
首先,从lock_guard<>可以看出它是一个模板类,它在自身作用域(生命周期)中具有构造时加锁,析构时解锁的功能。 从VS中查看代码,不难发现,其设计的思路简单而又巧妙:
template <class _Mutex>
class lock_guard {
public:
using mutex_type = _Mutex;
explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) {
_MyMutex.lock();
}
lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {}
~lock_guard() noexcept {
_MyMutex.unlock();
}
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
private:
_Mutex& _MyMutex;
};
四、总结
std::lock_guard是非常巧妙的一种设计思路,利用类对象的生命周期,构造时使互斥量加锁,析构时使互斥量解锁,从而实现其作用域内对互斥量的管理。
|