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等方法决定上锁和解锁

std::shared_mutex shared_mutexx;
void readData()
{
    
    
}

递归锁,递归锁的效果和普通互斥锁相同,它和普通互斥锁的区别在于它可以多次假锁,多次解锁,解锁的次数应该同加锁的次数相同。
当两个函数foo和goo获得了同一个锁,而函数foo需要调用goo时,该特性就派上用场了。

猜你喜欢

转载自blog.csdn.net/weixin_43448686/article/details/106572907