5

In what situations would one use the release method of std::unique_lock ? I made the mistake of using the release method instead of the unlock method and it took a while to understand why the following code wasn't working.

#include <mutex>
#include <iostream>
#include <vector>
#include <thread>
#include <chrono>

std::mutex mtx;

void foo()
{    
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "in critical section\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
    lock.release();
}

int main()
{
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i)
        threads.push_back(std::thread(foo));

    for (std::thread& t : threads)
        t.join();
}
tcb
  • 4,408
  • 5
  • 34
  • 51

2 Answers2

7

There's a good use for it in this answer where ownership of the locked state is explicitly transferred from a function-local unique_lock to an external entity (a by-reference Lockable parameter).

This concrete example is typical of the use: To transfer ownership of the locked state from one object (or even type) to another.

Community
  • 1
  • 1
Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
5

.release() is useful when you want to keep the mutex locked until some other object/code decides to unlock it... for example, if you were calling into a function that needed the mutex locked and would unlock it itself at a certain point in that function's processing, where that function accepts only a std::mutex& rather than a std::unique_lock<std::mutex>&&. (Conceptually similar to the uses for smart pointer release functions.)

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252