lock

unique_lock provide a way to defer lock and lock can lock two mutex at the same time to avoid dead-lock.

#include <mutex>
#include <thread>
#include <chrono>

struct Box {
    explicit Box(int num) : num_things{num} {}

    int num_things;
    std::mutex m;
};

void transfer(Box &from, Box &to, int num)
{
    // don't actually take the locks yet
    std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
    std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);

    // lock both unique_locks without deadlock
    std::lock(lock1, lock2);

    from.num_things -= num;
    to.num_things += num;

    // 'from.m' and 'to.m' mutexes unlocked in 'unique_lock' dtors
}

int main()
{
    Box acc1(100);
    Box acc2(50);

    std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);
    std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);

    t1.join();
    t2.join();
}

And it can transfer lock ownership to the caller since it can be movable.

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();
}

And unique_lock support lock, unlock method, you can release lock earlier if you don't need lock protection before unique_lock object destroy.

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(); 
  result_type result=process(data_to_process);
  my_lock.lock(); 
  write_result(data_to_process,result);
}

From unique_lock ref

c++
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License