在研究vins-mono源代码时,读取IMU数据和特征数据时,遇到了c++锁,所以学习了下锁。
C++锁可分为互斥锁、读写锁(共享锁),递归锁;
std::mutex mutexx;//普通锁互斥锁 //包含在头文件<mutex>
std::recursive_mutex recursive_mutexx; //递归锁 //包含在头文件<recursive_mutex >
std::shared_mutex shared_mutexx; //读写锁 //包含在头文件<shared_mutex>
互斥锁是为了避免数据竞争而产生的,即避免多个线程同时访问同一个数据。当某个线程加上互斥锁后,其他线程就阻塞等待该线程的锁解放后获取这个锁。以下列代码为例。
void helloguangzhou()
{
int i = 10;
while (i--) {
cout << " hello guangzhou" << endl;
}
}`
void hellowworld()
{
int i = 10;
while (i--)
{
cout << " hello world" << endl;
}
}
int main()
{
std::thread t1(helloguangzhou);
std::thread t2(hellowworld);
t1.detach();
t2.detach();
system("pause");
return 0;
}
输出为图下所示,这看起来比较混乱。
hello guangzhou hello world
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello world
hello world
hello guangzhou
hello world
hello guangzhou
hello world
hello world
hello guangzhou
hello world
hello world
hello world
hello world
如果两个线程函数分别加上锁,即
std::mutex mutexx;
void helloguangzhou()
{
mutexx.lock();
int i = 10;
while (i--) {
cout << " hello guangzhou" << endl;
}
mutexx.unlock();
}`
void hellowworld()
{
mutexx.lock();
int i = 10;
while (i--)
{
cout << " hello world" << endl;
}
mutexx.unlock();
}
则它的输出为
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello guangzhou
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
读写锁是为了在多个线程访问同一个数据时,只能有一个线程可以修改该数据,其他线程只能访问。
读写锁分为读模式和写模式两种,在读模式情况下,写模式线程被阻塞,其他读模式线程可以访问,即读模式共享;
在写模式情况写,读模式阻塞,其它写模式线程也阻塞,即写入唯一。这满足了读写锁只有一个线程可以修改数据,多个线程可以同时访问数据的条件。
写模式用lock(),unlock(),unique_lock等方法决定上锁和解锁,读模式用share_lock(),share_unlock(),shared_lock等方法决定上锁和解锁
https://blog.csdn.net/weixin_43448686/article/details/106572907