【问题标题】:Is try_lock() +unlock() valid way to check whether boost::interprocess::file_lock is locked?try_lock() +unlock() 是检查 boost::interprocess::file_lock 是否被锁定的有效方法吗?
【发布时间】:2015-11-04 14:40:10
【问题描述】:

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

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

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

【问题讨论】:

  • 解锁后,您就会意识到此信息已过时。这与在不打开文件的情况下检查文件是否存在相同的问题。检查后状态可能会立即更改。不要根据结果做出关键决定,否则会引入微妙的竞争条件。
  • @JohnKugelman 好点。答案是否定的,我想,唯一有效的方法是锁定并做这些事情。
  • 您为tryLockunlock 创建了一个接口函数并使用它们?
  • @sehe:发表了我的意思作为答案
  • @SimonKraemer 发帖 my response 到那个

标签: c++ boost boost-interprocess


【解决方案1】:

虽然另一个答案是不引入竞态条件的关键,但没有理由放弃使用正确的 RAII 包装器(如 std::lock_guard<> 和 @)所带来的异常安全性和错误恢复能力987654323@.

你想写:

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

【讨论】:

  • 附言。请注意,unique_lock 是可移动的,因此您可以使 try_lock_guard 可轻松移动(我回来时会这样做)
  • +1 as RAII 应该是首选方式。我没有测试它,但不应该 unique_lock 组合 std::try_to_lock 在没有包装器的情况下做几乎相同的事情吗? if (auto lk = std::unique_lock&lt;std::mutex&gt;(mx, std::try_to_lock)){...}。如果DataCache 提供函数lockunlocktry_lock,这也应该有效
  • 哦,嘿。 try_to_lock 对我来说是新的。更令人费解的是,显式的bool-conversion 也已经存在。简化了我的回答:)
  • 我们每天都会学到一些新东西。我也很惊讶地发现这一点。 :-)
【解决方案2】:

因为这不适合评论:您可以在外部为 tryLockunlock 创建“接口函数”。

例如:

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 是否可以在这里使用。我只是从问题代码中复制的。

【讨论】:

  • 是的,这将是正确的方法。实际情况是,就我而言,我意识到我什至不知道 locked 方法的含义是什么,但你的回答对于任何将要这样做的人来说都是正确的。
  • 哦,好吧。如果这回答了这个问题,我建议使用像if (auto lk = try_lock(cache)) { .... } 这样的成语和 RAII。一会儿再发帖(忙着带孩子)
猜你喜欢
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多