Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scoped_lock with a timeout?

Tags:

c++

Is it possible to have a scoped_lock with a timeout to wait N seconds/millis to acquire the lock?

I see no mention here:

https://en.cppreference.com/w/cpp/thread/scoped_lock.html

I can see std::timed_mutex but in all the examples it seems to be explicitly released via .unlock()?

I see Boost might have one, but then I cannot use std chrono for timeouts etc.

Otherwise I'll have to write my own

like image 480
mezamorphic Avatar asked Jul 29 '26 01:07

mezamorphic


2 Answers

std::scoped_lock is the utility that will call unlock() in destructor on all owned mutexes. So wherever in the example you have unlock() call, you can mentally replace it by "std::scoped_lock-end-of-life".

Do note that you need std::adopt_lock if you want to use timeout versions of try_lock(), as std::scoped_lock doesn't know how to use them:

std::timed_mutex m;
if (m.try_lock_for(1s)) {
    std::scoped_lock lock {std::adopt_lock, m};
    // you have mutex here, it will be released automatically at the end of scope
} else {
    // you didn't acquire mutex
}
like image 171
Yksisarvinen Avatar answered Jul 31 '26 15:07

Yksisarvinen


The language of your question implies a single mutex that you are trying to perform a timed lock on with an RAII device. If that is the case, std::unique_lock paired with a std::timed_mutex is the tool you are looking for.

#include <mutex>
#include <chrono>
#include <iostream>

std::timed_mutex mut;

int
main()
{
    using namespace std::literals;
    std::unique_lock lk{mut, 157ms};  // or 3s, 6ns, whatever
    if (lk.owns_lock())
        std::cout << "Got it\n";
    else
        std::cout << "Didn't get it\n";
}

If you meant a device for a timed wait on locking multiple mutexes, that is not currently in the standard. I have seen interest in adding that functionality to the standard though.

If desired, you can use the same syntax to try until a time_point:

auto tp = std::chrono::steady_clock::now() + 3s;
// Do other work...
std::unique_lock lk{mut, tp};
if (lk.owns_lock()) // ...

In either case, lk will unlock the mutex when it goes out of scope if (and only if) it obtained the lock in the timed try lock, and has not been previously released with lk.unlock().

like image 27
Howard Hinnant Avatar answered Jul 31 '26 15:07

Howard Hinnant



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!