详解C++ 共享数据保护机制攻略
什么是共享数据
共享数据是指多个线程同时访问同一数据,而且每个线程都可以修改数据。因为多个线程同时访问同一数据,所以需要额外的保护机制来避免数据竞争和错误的结果。
数据保护机制
常见的数据保护机制有:
1. 互斥锁(Mutex)
互斥锁是一种最常用的保护共享数据的方法,即通过加锁(lock)来保护共享数据。同一时间只有一个线程可以持有锁,其他线程需要等待锁的释放才能继续访问共享数据。互斥锁的使用方式如下:
#include <mutex>
std::mutex mtx; //初始化一个互斥锁
//使用互斥锁保护共享数据
mtx.lock(); //加锁
//访问共享数据
mtx.unlock(); //解锁
2. 条件变量(Condition Variable)
条件变量用于在共享资源状态发生改变时通知等待的线程。当共享变量发生变化时,线程可以通过发出通知来通知其他线程。条件变量的使用方式如下:
#include <condition_variable>
std::mutex mtx; //初始化一个互斥锁
std::condition_variable cv; //初始化一个条件变量
//线程A等待变量cond变为true
std::unique_lock<std::mutex> ul(mtx);
while(!cond) {
cv.wait(ul); //等待条件变量的通知
}
//线程B改变cond变量的值,并通知等待的线程
std::lock_guard<std::mutex> lg(mtx);
cond = true;
cv.notify_all(); //通知所有等待的线程
3. 读写锁(Read-Write Lock)
读写锁是一种特殊的锁,读写锁允许多个线程同时读取共享数据,但是只允许一个线程写共享数据。这种锁可以提高读性能,适用于大部分读比写多的场合。读写锁的使用方式如下:
#include <shared_mutex>
std::shared_mutex rw_lock; //初始化一个读写锁
//使用读锁保护共享数据
std::shared_lock<std::shared_mutex> sl(rw_lock);
//访问共享数据
//使用写锁保护共享数据
std::unique_lock<std::shared_mutex> ul(rw_lock);
//修改共享数据
示例说明
示例1:使用互斥锁保护共享数据
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx; //初始化互斥锁
int count = 0; //共享数据
void increment() {
mtx.lock(); //加锁
for(int i = 0; i < 1000000; ++i) {
++count; //访问共享数据
}
mtx.unlock(); //解锁
}
int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Count = " << count << std::endl;
return 0;
}
在该示例中,定义了一个互斥锁来保护共享数据count
,t1
和t2
同时运行,但是同一时间只有一个线程可以持有锁,另一个线程需要等待锁的释放。通过互斥锁的加锁和解锁操作来保证数据安全。
示例2:使用读写锁保护共享数据
#include <iostream>
#include <thread>
#include <shared_mutex>
std::shared_mutex rw_lock; //初始化读写锁
int count = 0; //共享数据
void read() {
std::shared_lock<std::shared_mutex> sl(rw_lock); //加读锁
std::cout << "Count = " << count << std::endl; //读取共享数据
}
void write() {
std::unique_lock<std::shared_mutex> ul(rw_lock); //加写锁
++count; //修改共享数据
}
int main() {
std::thread t1(read);
std::thread t2(write);
std::thread t3(read);
t1.join();
t2.join();
t3.join();
return 0;
}
在该示例中,定义了一个读写锁来保护共享数据count
,示例中三个线程分别进行读操作和写操作,读取共享数据时使用读锁保护,修改共享数据时使用写锁保护。因为读写锁可以并发读取操作,所以可以在读线程之间保持较高的并发性能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解C++ 共享数据保护机制 - Python技术站