Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why no timeout support in std::lock?

Tags:

c++

c++11

locking

If I want to grab multiple locks without running the risk of deadlock, I can use the std::lock function:

int data1, data2;
std::mutex m1, m2;
std::unique_lock<std::mutex> lock1(m1, std::defer_lock);
std::unique_lock<std::mutex> lock2(m2, std::defer_lock);

std::lock(lock1, lock2);           // guaranteed deadlock-free

// work with data1 and data2

But what if I want to acquire the locks within a specified period and timeout otherwise? Is there a reason there is nothing like try_until for locks that's akin to wait_until for futures and condition variables?

like image 672
KnowItAllWannabe Avatar asked Sep 24 '12 16:09

KnowItAllWannabe


2 Answers

Why no timeout support in std::lock?

  1. Because no one proposed it.

  2. Because this area was so controversial that the less proposed, the more likely to get it accepted.

  3. Because we were afraid that if we standardized everything, you would get bored.

  4. It was left as an exercise for the reader.

Hmm... I'm running out of ideas... :-)

Oh!

It is easy for you to do yourself if you need it:

Update

Here's a rewrite I like better:

#include <mutex>
#include <chrono>

template <class Clock, class  Duration, class L0, class L1>
int
try_lock_until(std::chrono::time_point<Clock, Duration> t, L0& l0, L1& l1)
{
    std::unique_lock<L0> u0(l0, t);
    if (u0.owns_lock())
    {
        if (l1.try_lock_until(t))
        {
            u0.release();
            return -1;
        }
        else
            return 1;
    }
    return 0;
}

template <class Rep, class  Period, class L0, class L1>
int
try_lock_for(std::chrono::duration<Rep, Period> d, L0& l0, L1& l1)
{
    return try_lock_until(std::chrono::steady_clock::now() + d, l0, l1);
}


int main()
{
    std::timed_mutex  m1, m2;
    try_lock_for(std::chrono::milliseconds(50), m1, m2);
}

As Anthony suggests, feel free to propose this. Also feel free to just use it, and let us know if it was actually useful or not.

like image 154
Howard Hinnant Avatar answered Oct 09 '22 03:10

Howard Hinnant


std::timed_mutex has try_lock_until and try_lock_for member functions. However, you are right that there is no equivalent of std::lock with a timeout.

Locking a mutex with a timeout is only of use in particular niches. Locking multiple mutexes with a timeout was not something anyone felt strongly enough about to propose, so it isn't in C++11.

The standards committee is currently actively seeking proposals for the next standard. If you feel that a timeout-aware equivalent of std::lock is valuable, why not write a proposal?

like image 37
Anthony Williams Avatar answered Oct 09 '22 04:10

Anthony Williams