互斥锁、读写锁和自旋锁的使用场景
时间: 2024-05-23 11:16:09 浏览: 9
互斥锁、读写锁和自旋锁都是用来保护共享资源的并发访问的。它们的使用场景如下:
1. 互斥锁:适用于保护临界区,即一次只能有一个线程访问的共享资源。当一个线程获得互斥锁时,其他线程会被阻塞,直到该线程释放锁。互斥锁适用于读写操作不频繁、临界区较小的情况。
2. 读写锁:适用于读操作比写操作频繁的场景。读写锁允许多个线程同时读取共享资源,但在写操作时必须独占锁。当有写操作时,所有读操作都会被阻塞,直到写操作完成。读写锁适用于读操作占比较大的场景,可以提高并发性能。
3. 自旋锁:适用于保护临界区,且临界区很小的场景。自旋锁不会使线程阻塞,而是在获取锁失败时,不停地尝试获取锁,直到获取成功。自旋锁适用于临界区很小,线程获取锁的时间很短的场景,可以避免线程上下文切换的开销。
相关问题
自旋锁、互斥锁、读写锁
自旋锁、互斥锁和读写锁是多线程编程中常用的同步机制,它们用于保护共享资源的访问。
1. 自旋锁(Spin Lock):自旋锁是一种基于忙等待的锁,线程在获取锁时若发现锁被其他线程占用,则会一直忙等待,不会阻塞自己。适用于锁持有时间很短,且并发竞争不激烈的情况。由于自旋锁忙等待时会占用CPU资源,所以在多核处理器上使用较为合适。
2. 互斥锁(Mutex Lock):互斥锁是一种阻塞锁,线程在获取锁时若发现锁被其他线程占用,则会阻塞自己,直到拥有锁的线程释放锁。适用于锁持有时间较长或者并发竞争较激烈的情况。互斥锁可以保证资源的独占性,但存在线程阻塞和唤醒的开销。
3. 读写锁(Read-Write Lock):读写锁允许多个线程同时读取共享资源,但只允许一个线程进行写操作。读写锁适用于读操作远远多于写操作的场景,可以提高并发性能。读写锁的特点是在读线程不会阻塞的情况下,写线程才能获取到锁。这样可以避免写线程长时间等待,提高了读操作的并发度。
总结:自旋锁适用于锁持有时间短、并发度低的场景;互斥锁适用于锁持有时间长、并发竞争激烈的场景;读写锁适用于读操作频繁、写操作较少的场景。选择合适的同步机制可以提高多线程程序的性能和并发度。
请给出互斥锁、读写锁以及自旋锁和递归锁的用法实例
1. 互斥锁
互斥锁用于保护共享资源,确保同一时刻只有一个线程能够访问该资源。实例代码如下:
```C++
#include <mutex>
#include <thread>
#include <iostream>
std::mutex mtx;
void print_func(int num) {
mtx.lock();
std::cout << "Thread " << num << " is printing." << std::endl;
mtx.unlock();
}
int main() {
std::thread t1(print_func, 1);
std::thread t2(print_func, 2);
t1.join();
t2.join();
return 0;
}
```
2. 读写锁
读写锁用于在读多写少的场景中提高效率,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。实例代码如下:
```C++
#include <iostream>
#include <thread>
#include <shared_mutex>
std::shared_mutex rw_mutex;
int shared_data = 0;
void read_func(int num) {
rw_mutex.lock_shared();
std::cout << "Thread " << num << " read shared_data: " << shared_data << std::endl;
rw_mutex.unlock_shared();
}
void write_func(int num) {
rw_mutex.lock();
shared_data = num;
std::cout << "Thread " << num << " wrote shared_data: " << shared_data << std::endl;
rw_mutex.unlock();
}
int main() {
std::thread t1(write_func, 1);
std::thread t2(read_func, 2);
std::thread t3(read_func, 3);
t1.join();
t2.join();
t3.join();
return 0;
}
```
3. 自旋锁
自旋锁适用于短时间内需要等待的场景,可以减少线程切换带来的开销。实例代码如下:
```C++
#include <iostream>
#include <thread>
#include <atomic>
std::atomic_flag spin_lock = ATOMIC_FLAG_INIT;
int shared_data = 0;
void add_func(int num) {
while (spin_lock.test_and_set(std::memory_order_acquire));
shared_data += num;
spin_lock.clear(std::memory_order_release);
}
int main() {
std::thread t1(add_func, 1);
std::thread t2(add_func, 2);
t1.join();
t2.join();
std::cout << "shared_data: " << shared_data << std::endl;
return 0;
}
```
4. 递归锁
递归锁允许同一线程多次获取锁,避免死锁。实例代码如下:
```C++
#include <iostream>
#include <thread>
#include <mutex>
std::recursive_mutex mtx;
int shared_data = 0;
void add_func(int num) {
mtx.lock();
shared_data += num;
if (num > 1) {
add_func(num - 1);
}
mtx.unlock();
}
int main() {
std::thread t1(add_func, 3);
t1.join();
std::cout << "shared_data: " << shared_data << std::endl;
return 0;
}
```
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![pptx](https://img-home.csdnimg.cn/images/20210720083543.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)