unique_lock
unique_lock是一个对象,它在两个状态中都拥有唯一所有权的互斥对象:锁定和解锁。
在构造上(或者通过移动分配给它),对象获得一个互斥对象,由它的锁定和解锁操作负责。
该对象支持两种状态:锁定和解锁。
该类保证了销毁时处于的解锁的状态(即使没有显式地调用)。因此,它作为具有自动持续时间的对象特别有用,因为它可以保证互斥对象在抛出异常时被正确地解锁。
但是请注意,uniquelock对象并不以任何方式管理互斥对象的生命周期:互斥对象的持续时间至少会扩展到管理它的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;
}
第二个例子是对于成员lock的操作,单线程操作顺序如何通过加锁来管理
#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <chrono>
int main()
{
int counter = 0;
std::mutex counter_mutex,counter_mutexA;
std::vector<std::thread> threads;
auto worker_task = [&](int id) {
// Note, this is just lock! See the document of the constructor.
std::unique_lock<std::mutex> lock(counter_mutex);
++counter;
std::cout << id << ", initial counter: " << counter << '\n';
lock.unlock();
don't hold the lock while we simulate an expensive operation
std::this_thread::sleep_for(std::chrono::seconds(1));
lock.lock();
//std::unique_lock<std::mutex>lock1(counter_mutexA);
++counter;
std::cout << id << ", final counter: " << counter << '\n';
};
for (int i = 0; i < 10; ++i) {
// vector::push_back() cannot work due to std::thread is not copyable.
threads.emplace_back(worker_task, i);
}
for (auto &thread : threads) thread.join();
getchar();
return 0;
}