[c++11 concurrent programming] 08-mutex Std::unique_lock

Source: Internet
Author: User

Std::unique_lock is more flexible than Std::lock_guard, Std::unique_lock does not have a mutex associated with it. The second parameter of the constructor can be specified as std::d Efer_lock, which means that the incoming mutex remains unlock state when the Unique_lock is constructed. The mutex is then locked by invoking the lock () method of the Std::unique_lock object or by passing the Std::unique_lock object into the Std::lock () method.

#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;        Constructs the Unique_lock, maintains the mutex as unlocked state        std::unique_lock<std::mutex> lock_a (lhs.m,std::d efer_lock);        Std::unique_lock<std::mutex> Lock_b (rhs.m,std::d efer_lock);        Lock Mutex        std::lock (lock_a,lock_b);        Swap (Lhs.some_detail,rhs.some_detail);    }}; int main () {}

Std::unique_lock requires more space than std::lock_guard because it needs to store whether the mutex it is associated with is locked, and if it is locked, it needs to unlock the mutex it is associated with when it is being refactored. The performance of the Std::unique_lock is also slightly worse than that of Std::lock_guard, because the lock or unlock mutex also needs to update the flag of whether the mutex is locked. In most cases, it is recommended to use Std::lock_guard but if you need more flexibility, such as the example above, or you need to pass lock ownership between the code, you can use Std::unique_lock.

Std::unique_lock does not have ownership of the Mutex,mutex associated with it can be passed between different instances. For example, we expect to provide a function that, after locking a mutex, returns the ownership of the mutex to the caller, which allows the caller to perform additional operations under the protection of the mutex. As shown in the Get_lock () function, after locking the mutex, executing prepare_data (), and then returning the mutex to the caller, the caller passes the mutex to its own local variable std::unique_lock, and then the protection of the mutex is lowered with do _something (). When Process_data () exits, the mutex is automatically unlock.

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's flexibility is also that we can actively invoke the unlock () method to release the mutex, because the longer the lock, the more it affects the performance of the program, and in some special cases, releasing the mutex early can improve the efficiency of the program execution.

In addition, we also need to pay attention to the granularity of the lock, if there are multiple threads waiting for the same resource, and a thread holding the mutex for a long time, it will increase the wait time for other threads. We try to ensure that only shared data is locked and data is processed outside of the locked range. Do not perform I/O operations in the case of locking mutexes, because I/O operations are slow. You can call Std::unique_lock's unlock () operation to release the mutex if necessary, and then call Lock () when needed to lock the 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 (); Lock Mutex    result_type result=process (data_to_process) is not required in process;    My_lock.lock (); Lock the mutex again before the write operation    

In the swap instance, we locked the mutex for two objects and then compared the swap operation. Assuming that we want to compare two objects, and the cost of copying objects is small, consider reducing the scope and time of the mutex protection, copying the object when the mutex is locked, releasing the mutex, and using two replicated objects for the comparison operation.

#include <mutex>class y{private:    int some_detail;    Mutable Std::mutex m;    Returns the copy of the object    int get_detail () const    {        //Protected Object        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;        Gets the copy of the object to compare the        int const lhs_value=lhs.get_detail ();        int const rhs_value=rhs.get_detail ();        Copy of the Comparison object        return lhs_value==rhs_value;}    ; int main () {}

This approach, while reducing the scope and time of the mutex lock, has changed the semantics of the comparison. Because this implementation only guarantees that the Lhs.some_detail read at one time is equal to the rhs.some_detail read at another moment, there is race condition between reading Lhs_value and reading Lrh_value, Their values may have been modified.




Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

[c++11 concurrent programming] 08-mutex Std::unique_lock

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.