二者都是 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_lockstd::mutex mtx; // mutex for critical sectionvoid 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;
}
?