try_lock() +unlock() 是检查 boost::interprocess::file_lock 是否被锁定的有效方法吗?

Is try_lock() +unlock() valid way to check whether boost::interprocess::file_lock is locked?

我需要使用 boost::interprocess::file_lock 检查文件是否被锁定。我制作了这个,但我担心它会做什么:

bool DataCache::isLocked() const {
    bool res = lock_->try_lock();
    if(res)
        lock_->unlock();
    return res;
}

这是个好主意吗?有没有不加锁就能查看的方法?

因为这不适合评论:您可以在外部为 tryLockunlock 创建 "interface functions"。

例如:

bool DataCache::try_lock() const {
    return lock_->try_lock();
}

void DataCache::unlock() const {
    lock_->unlock();
}

用法:

DataCache cache;
if(cache.try_lock())
{
    cache.doSomething();
    cache.unlock();
}
else
{
    //....
}

我不确定 const 在这里是否有效。我只是从问题代码中复制的。

虽然另一个答案是不引入竞争条件的关键,但没有理由放弃使用适当的 RAII 包装器(如std::lock_guard<>std::unique_lock<>.

你想写:

if (auto lk = try_to_lock(mx)) {
    std::cout << "simple test\n";
} // automatically unlocks at scope exit

你可以。这是我的简单实现:

template <typename Lockable>
std::unique_lock<Lockable> try_to_lock(Lockable& lockable) {
    return std::unique_lock<Lockable> (lockable, std::try_to_lock);
}

Live On Coliru

#include <mutex>
#include <iostream>

int main() {
    // demo
    std::mutex mx;

    if (auto lk = try_to_lock(mx)) {
        std::cout << "simple test\n";
    } // automatically unlocks at scope exit

    if (auto lk = try_to_lock(mx)) {
        std::cout << "yes\n";

        if (auto lk = try_to_lock(mx)) {
            std::cout << "oops?!\n"; // not reached
        } else {
            std::cout << "no recursive lock\n";
        }

        // but you can manipulate the lock if you insist:
        lk.unlock();

        if (auto lk = try_to_lock(mx)) {
            std::cout << "now we can lock again\n";
        } else {
            std::cout << "oops?!\n"; // not reached
        }
    }
}

打印:

simple test
yes
no recursive lock
now we can lock again