标签:c++11 concurrency unique_lock
相对于std::lock_guard来说,std::unique_lock更加灵活,std::unique_lock不拥有与其关联的mutex。构造函数的第二个参数可以指定为std::defer_lock,这样表示在构造unique_lock时,传入的mutex保持unlock状态。然后通过调用std::unique_lock对象的lock()方法或者将将std::unique_lock对象传入std::lock()方法来锁定mutex。
#include <mutex> class some_big_object {}; void swap(some_big_object& lhs,some_big_object& rhs) {} class X { private: some_big_object some_detail; mutable std::mutex m; public: X(some_big_object const& sd):some_detail(sd){} friend void swap(X& lhs, X& rhs) { if(&lhs==&rhs) return; // 构造unique_lock,保持mutex为unlocked状态 std::unique_lock<std::mutex> lock_a(lhs.m,std::defer_lock); std::unique_lock<std::mutex> lock_b(rhs.m,std::defer_lock); // lock mutex std::lock(lock_a,lock_b); swap(lhs.some_detail,rhs.some_detail); } }; int main() {}
std::unique_lock并不拥有与其关联的mutex,mutex的所有权可以在不同的实例之间进行传递。比如我们期望提供一个函数,在锁定mutex后,将mutex的所有权返回给调用者,这样可以让调用者在mutex的保护下,执行更多额外的操作。如下所示的get_lock()函数,锁定mutex后,执行prepare_data(),然后将mutex返回给调用者,调用者将mutex传入其自己的局部变量std::unique_lock,然后mutex的保护下调用do_something()。当process_data()退出时,会自动unlock这个mutex。
std::unique_lock<std::mutex> get_lock() { extern std::mutex some_mutex; std::unique_lock<std::mutex> lk(some_mutex); prepare_data(); return lk; } void process_data() { std::unique_lock<std::mutex> lk(get_lock()); do_something(); }std::unique_lock的灵活性还在于我们可以主动的调用unlock()方法来释放mutex,因为锁的时间越长,越会影响程序的性能,在一些特殊情况下,提前释放mutex可以提高程序执行的效率。
此外,我们还需要注意锁的粒度,如果有多个线程等待相同的资源,而某个线程长时间的持有mutex,就会增加其它线程的等待时间。我们要尽量保证只对共享数据加锁,在锁定范围之外对数据进行处理。不要在锁定mutex的情况下执行I/O操作,因为I/O操作是很慢的。可以在必要的情况下调用std::unique_lock的unlock()操作来释放mutex,在需要时,再调用lock()来锁定mutex。
void get_and_process_data() { std::unique_lock<std::mutex> my_lock(the_mutex); some_class data_to_process=get_next_data_chunk(); my_lock.unlock(); // 在process中不需要锁定mutex result_type result=process(data_to_process); my_lock.lock(); // 在写操作前再次锁定mutex write_result(data_to_process,result); }
#include <mutex> class Y { private: int some_detail; mutable std::mutex m; // 返回对象的拷贝 int get_detail() const { // 保护对象 std::lock_guard<std::mutex> lock_a(m); return some_detail; } public: Y(int sd):some_detail(sd){} friend bool operator==(Y const& lhs, Y const& rhs) { if(&lhs==&rhs) return true; // 获取要比较对象的拷贝 int const lhs_value=lhs.get_detail(); int const rhs_value=rhs.get_detail(); // 比较对象的拷贝 return lhs_value==rhs_value; } }; int main() {}
版权声明:本文为博主原创文章,未经博主允许不得转载。
[C++11 并发编程] 08 - Mutex std::unique_lock
标签:c++11 concurrency unique_lock
原文地址:http://blog.csdn.net/yamingwu/article/details/47841689