二者都是 C++ 标准库中用于管理互斥锁(mutex)的 RAII(Resource Acquisition Is Initialization)机制的类。这些类可以确保互斥锁在构造时被获取,在析构时被释放,从而避免死锁和资源泄漏问题。不过,它们在功能和使用方式上有一些重要区别。
std::lock_guard
td::lock_guard
是一个简单的、轻量级的锁管理器,它在构造时获取锁,在析构时释放锁。其主要特点是不能显式地解锁或重新锁定。
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;
void threadFunction(int threadID) {
try {
std::lock_guard<std::mutex> lock(mtx);
// mtx 在此范围内锁定
std::cout << "Thread " << threadID << " is running..." << std::endl;
// 模拟一些工作
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Thread " << threadID << " has finished working." << std::endl;
// mtx 在此范围末尾解锁
} catch (const std::exception& e) {
std::cerr << "Exception caught in thread " << threadID << ": " << e.what() << std::endl;
}
}
int main() {
const int numThreads = 5;
std::vector<std::thread> threads;
for (int i = 0; i < numThreads; ++i) {
threads.emplace_back(threadFunction, i);
}
for (auto& t : threads) {
t.join();
}
std::cout << "All threads have completed." << std::endl;
return 0;
}
每个线程在输出信息时获取了互斥锁,确保了标准输出的操作是原子的,避免了竞争条件导致的输出混乱。
std::unique_lock
std::unique_lock
是一个灵活但稍复杂的锁管理器。它允许更多的锁操作,如延迟锁定、解锁和重新锁定。
// unique_lock example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
std::mutex mtx; // mutex for critical section
void print_block (int n, char c) {
// critical section (exclusive access to std::cout signaled by lifetime of lck):
std::unique_lock<std::mutex> lck (mtx);
for (int i=0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
}
int main ()
{
std::thread th1 (print_block,50,'*');
std::thread th2 (print_block,50,'$');
th1.join();
th2.join();
return 0;
}
order of lines may vary, but characters are never mixed.
void threadFunction() {
std::unique_lock<std::mutex> lock(mtx);
// 可以显式解锁
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟工作
std::cout << "Thread is running..." << std::endl;
lock.unlock();
// 可以重新加锁
lock.lock();
std::cout << "Thread is finishing..." << std::endl;
}
int main() {
std::thread t1(threadFunction);
std::thread t2(threadFunction);
t1.join();
t2.join();
return 0;
}