C++线程中几类锁的详解
前言
在多线程编程中,锁是一种重要的同步机制,可以保证多个线程在访问共享资源时的安全性。C++提供了多种类型的锁,本篇文章将对常用的几种锁进行详解。
互斥锁(mutex)
互斥锁是最常用的一种锁,它保证同一时刻只有一个线程可以访问共享资源。当一个线程获得锁时,其他线程将一直等待直到拥有锁的线程释放锁为止。
创建互斥锁
C++标准库提供了std::mutex
类实现互斥锁,创建一个互斥锁的方法如下:
std::mutex mutexObj;
加锁和解锁
互斥锁的加锁和解锁操作分别使用std::mutex
类的lock()
和unlock()
方法实现:
mutexObj.lock();
// 临界区代码
mutexObj.unlock();
互斥锁示例
下面是一个使用互斥锁保护共享资源的示例,其中共享资源为一个计数器,多个线程分别对计数器进行加一:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutexObj;
int count = 0;
void increaseCount()
{
mutexObj.lock();
for (int i=0; i<1000; i++) {
count++;
}
mutexObj.unlock();
}
int main()
{
std::thread t1(increaseCount);
std::thread t2(increaseCount);
t1.join();
t2.join();
std::cout << "count:" << count << std::endl;
return 0;
}
在上面的示例中,通过互斥锁的加锁和解锁操作保证了count
变量的安全性。如果不使用锁,那么多个线程同时访问count
变量将会引发数据竞争问题。
递归锁(recursive mutex)
递归锁是一种互斥锁的变体,它允许同一线程多次获得锁而不会引起死锁。当一个线程对已经拥有的锁再次加锁时,递归锁会记录加锁次数,并在解锁时相应的解锁次数。
创建递归锁
C++标准库提供了std::recursive_mutex
类实现递归锁,创建一个递归锁的方法如下:
std::recursive_mutex recursiveMutexObj;
加锁和解锁
递归锁的加锁和解锁操作分别使用std::recursive_mutex
类的lock()
和unlock()
方法实现。
递归锁示例
下面是一个使用递归锁保护共享资源的示例,其中共享资源为一个计数器,一个线程递归调用函数对计数器进行加一:
#include <iostream>
#include <thread>
#include <mutex>
std::recursive_mutex recursiveMutexObj;
int count = 0;
void increaseCount()
{
recursiveMutexObj.lock();
count++;
if (count < 1000) {
increaseCount();
}
recursiveMutexObj.unlock();
}
int main()
{
std::thread t1(increaseCount);
t1.join();
std::cout << "count:" << count << std::endl;
return 0;
}
在上面的示例中,通过递归锁的加锁和解锁操作保证了count
变量的安全性。虽然increaseCount()
方法递归调用了多次,但是由于使用了递归锁,所以不会引起死锁或者其他线程对共享资源的竞争问题。
读写锁(read-write lock)
读写锁是一种特殊的锁,对于共享资源可以允许多个线程同时进行读访问,但是在进行写访问时需要互斥。读写锁可以提高读取操作的并发性,提高程序性能。
创建读写锁
C++标准库提供了std::shared_timed_mutex
类实现读写锁,创建一个读写锁的方法如下:
std::shared_timed_mutex rwMutexObj;
读操作
对于读操作,可以使用std::shared_timed_mutex
类的lock_shared()
方法进行加锁,使用unlock_shared()
方法进行解锁:
rwMutexObj.lock_shared();
// 共享资源读取操作
rwMutexObj.unlock_shared();
当多个线程对共享资源进行读操作时,可以用读写锁来提高并发性,示例如下:
读写锁示例
下面是一个使用读写锁保护共享资源的示例,其中共享资源为一个计数器,多个线程可以同时对计数器进行读取,但是对计数器进行写操作时需要互斥:
#include <iostream>
#include <thread>
#include <shared_mutex>
std::shared_timed_mutex rwMutexObj;
int count = 0;
void increaseCount()
{
rwMutexObj.lock();
count++;
rwMutexObj.unlock();
}
void printCount()
{
rwMutexObj.lock_shared();
std::cout << "count:" << count << std::endl;
rwMutexObj.unlock_shared();
}
int main()
{
std::thread t1(increaseCount);
std::thread t2(printCount);
t1.join();
t2.join();
return 0;
}
在上面的示例中,通过读写锁的读和写操作,保证了count
变量的安全性。由于多个线程可以同时对count
变量进行读取,所以使用读写锁可以提高程序的并发性。
总结
本篇文章介绍了C++中常用的锁类型,包括互斥锁、递归锁和读写锁。通过适当的锁机制可以保证多线程访问共享资源的安全性,提高程序的并发性。在实际应用中应根据具体情况选择合适的锁机制,以达到最优的性能和安全性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++线程中几类锁的详解 - Python技术站