优化思路
- 细粒度锁:将共享资源按访问频率或功能拆分成多个子部分,为每个子部分分配单独的锁。这样不同线程在访问不同子部分时不会相互阻塞。
- 读写锁:如果共享资源的读操作远多于写操作,可以使用读写锁。读操作时允许多个线程同时进行,写操作时则独占资源,防止其他读写操作。
- 无锁数据结构:对于某些数据结构,如栈、队列等,可以使用无锁数据结构来避免锁带来的开销。这些数据结构通常使用原子操作实现。
- 锁粗化:如果在一段代码中频繁获取和释放同一把锁,可以将锁的作用范围扩大,减少锁的获取和释放次数。
关键代码示例
- 细粒度锁示例
#include <mutex>
#include <thread>
#include <vector>
std::mutex mutex1, mutex2;
int data1 = 0;
std::vector<int> data2;
void threadFunction1() {
for (int i = 0; i < 1000000; ++i) {
std::lock_guard<std::mutex> lock(mutex1);
data1++;
}
}
void threadFunction2() {
for (int i = 0; i < 1000000; ++i) {
std::lock_guard<std::mutex> lock(mutex2);
data2.push_back(i);
}
}
- 读写锁示例
#include <shared_mutex>
#include <thread>
#include <iostream>
std::shared_mutex rwMutex;
int sharedData = 0;
void readFunction() {
std::shared_lock<std::shared_mutex> lock(rwMutex);
std::cout << "Read data: " << sharedData << std::endl;
}
void writeFunction() {
std::unique_lock<std::shared_mutex> lock(rwMutex);
sharedData++;
std::cout << "Write data: " << sharedData << std::endl;
}
- 无锁数据结构示例(以无锁栈为例)
#include <atomic>
#include <memory>
template<typename T>
class LockFreeStack {
private:
struct Node {
T data;
std::unique_ptr<Node> next;
Node(const T& value) : data(value) {}
};
std::atomic<Node*> head;
public:
LockFreeStack() : head(nullptr) {}
void push(const T& value) {
auto newNode = std::make_unique<Node>(value);
Node* oldHead = head.load();
do {
newNode->next = std::move(oldHead);
} while (!head.compare_exchange_weak(oldHead, newNode.release()));
}
bool pop(T& value) {
Node* oldHead = head.load();
do {
if (!oldHead) return false;
Node* newHead = oldHead->next.get();
} while (!head.compare_exchange_weak(oldHead, newHead));
value = std::move(oldHead->data);
return true;
}
};
- 锁粗化示例
#include <mutex>
#include <thread>
#include <vector>
std::mutex globalMutex;
std::vector<int> globalData;
void oldThreadFunction() {
for (int i = 0; i < 1000000; ++i) {
std::lock_guard<std::mutex> lock(globalMutex);
globalData.push_back(i);
}
}
void newThreadFunction() {
std::lock_guard<std::mutex> lock(globalMutex);
for (int i = 0; i < 1000000; ++i) {
globalData.push_back(i);
}
}