C++11各种锁的具体使用
在多线程编程时,锁是常用的线程同步机制之一。C++11中提供了多种不同的锁类型,用于处理不同的并发情况,本文将详细介绍这些锁的用法。
1、互斥锁(std::mutex
)
使用互斥锁可以实现对共享资源的互斥访问。
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex mtx; //定义互斥锁对象
void func(int id)
{
for(int i = 0; i < 5; ++i)
{
mtx.lock(); //获取互斥锁
std::cout << "Thread " << id << " : " << i << std::endl;
mtx.unlock(); //释放互斥锁
}
}
int main()
{
std::vector<std::thread> ths;
for(int i = 1; i <= 5; ++i)
{
ths.emplace_back(func, i);
}
for(auto& th : ths)
{
th.join();
}
return 0;
}
输出:
Thread 1 : 0
Thread 1 : 1
Thread 1 : 2
Thread 1 : 3
Thread 1 : 4
Thread 3 : 0
Thread 3 : 1
Thread 3 : 2
Thread 3 : 3
Thread 3 : 4
Thread 2 : 0
Thread 2 : 1
Thread 2 : 2
Thread 2 : 3
Thread 2 : 4
Thread 4 : 0
Thread 4 : 1
Thread 4 : 2
Thread 4 : 3
Thread 4 : 4
Thread 5 : 0
Thread 5 : 1
Thread 5 : 2
Thread 5 : 3
Thread 5 : 4
在函数func
中,使用互斥锁对cout流实现了互斥访问,从而避免线程之间的竞争。
2、递归互斥锁(std::recursive_mutex
)
递归互斥锁和普通互斥锁一样,它也可以保证对共享资源的互斥访问,但它允许同一线程多次获取互斥锁而不会死锁。
#include <iostream>
#include <mutex>
#include <vector>
std::recursive_mutex rmtx;
int recur(int n)
{
if(n <= 1)
return 1;
rmtx.lock();
int ret = n * recur(n - 1);
rmtx.unlock();
return ret;
}
int main()
{
std::vector<std::thread> ths;
for(int i = 1; i <= 5; ++i)
{
ths.emplace_back([i](){
std::cout << "Thread " << i << ": " << recur(5) << std::endl;
});
}
for(auto& th : ths)
{
th.join();
}
return 0;
}
输出:
Thread 1: 120
Thread 2: 120
Thread 3: 120
Thread 4: 120
Thread 5: 120
在递归函数recur
中,使用了递归互斥锁,允许同一线程多次获取互斥锁。
3、共享锁(std::shared_mutex
)
共享锁用于读写分离场景,多个线程可以同时持有共享锁(共享访问),但只有一个线程可以持有独占锁(排它访问)。
#include <iostream>
#include <shared_mutex>
#include <thread>
#include <vector>
std::shared_mutex smtx;
void read_func(int id)
{
smtx.lock_shared();
std::cout << "Thread " << id << ": read" << std::endl;
smtx.unlock_shared();
}
void write_func(int id)
{
smtx.lock();
std::cout << "Thread " << id << ": write" << std::endl;
smtx.unlock();
}
int main()
{
std::vector<std::thread> ths;
for(int i = 1; i <= 5; ++i)
{
if(i % 2 == 0)
ths.emplace_back(write_func, i);
else
ths.emplace_back(read_func, i);
}
for(auto& th : ths)
{
th.join();
}
return 0;
}
输出:
Thread 1: read
Thread 3: read
Thread 5: read
Thread 2: write
Thread 4: write
在函数read_func
中,使用共享锁对cout流实现了共享访问,在函数write_func
中,使用共享锁对cout流实现了排它访问。
4、条件变量锁(std::condition_variable
)
条件变量锁允许一个线程等待另一个线程满足特定条件时被唤醒。
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <thread>
std::mutex mtx;
std::condition_variable cv;
bool flag = false;
void func1()
{
std::unique_lock<std::mutex> lock(mtx);
std::cout << "func1 start" << std::endl;
flag = true;
lock.unlock();
cv.notify_one();
}
void func2()
{
std::unique_lock<std::mutex> lock(mtx);
while(!flag)
{
cv.wait(lock); //等待条件变量
}
std::cout << "func2 start" << std::endl;
}
int main()
{
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
输出:
func1 start
func2 start
在函数func1
中,改变了全局变量flag
的值,并使用了条件变量通知线程func2
,从而被唤醒。
以上就是C++11各种锁的详细介绍及对应的示例代码。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11各种锁的具体使用 - Python技术站