如何断言 std::mutex 是否被锁定?

2024-03-13

使用 GCC 4.8.2(在 Linux/Debian/Sid 64 位上)-或 GCC 4.9(如果可用)-在 C++11 中-我有一些互斥体

std::mutex gmtx;

actually, it is a static member in some class Foo containing both alpha and beta methods below.

它被锁在alpha like

void alpha(void) {
   std::lock_guard<std::mutex> g(gmtx);
   beta(void);
   // some other work
}

我想办理入住手续beta确实如此gmtx被锁住了:

void beta(void) {
   assert (gmtx.is_locked());
   // some real work
}

(notice that is_locked is only called inside assert... It can be very inefficient or even sometimes inaccurate)

当然,我还有其他函数调用beta, e.g.

void gamma(void) {
   std::lock_guard<std::mutex> g(gmtx);
   beta();
   // some other work
}

but is_locked不存在....我该如何定义它? (实际上我想确保互斥体已被某些[间接]调用者锁定在同一线程中......)

(我想测试它的原因assert就是它beta可以在其他地方调用)

我无法使用try_lock(除非使用递归互斥体),因为在常见情况下,它会锁定已经锁定的互斥体...(由调用者锁定在同一线程中),这不仅是未定义的行为,而且完全阻塞。

我想避免递归互斥体(比普通互斥体成本更高),除非我真的必须这样做。


NB: The real program is a bit more complex. Actually, all the methods are inside a class which maintain a naming bi-directional relation on "items". So I have inside that class a map from items to names and another from names to items. beta would be the internal method adding really a naming, and alpha and gamma would be the methods finding -or adding- an item by its name, or a name by its item.

PS: the real program is not yet released, but should become part of MELT http://gcc-melt.org/ - its future monitor http://gcc.gnu.org/ml/jit/2013-q4/msg00025.html; you can download it (alpha stage, very buggy) from here http://starynkevitch.net/Basile/monimelt-19feb2014.tgz (a temporary location)


严格来说,问题是关于检查锁定状态std::mutex直接地。但是,如果允许将其封装在一个新类中,则很容易做到:

class mutex :
    public std::mutex
{
public:
#ifndef NDEBUG
    void lock()
    {
        std::mutex::lock();
        m_holder = std::this_thread::get_id(); 
    }
#endif // #ifndef NDEBUG

#ifndef NDEBUG
    void unlock()
    {
        m_holder = std::thread::id();
        std::mutex::unlock();
    }
#endif // #ifndef NDEBUG

#ifndef NDEBUG
    bool try_lock()
    {
        if (std::mutex::try_lock()) {
            m_holder = std::thread::id();
            return true;
        }
        return false;
    }
#endif // #ifndef NDEBUG

#ifndef NDEBUG
    /**
    * @return true iff the mutex is locked by the caller of this method. */
    bool locked_by_caller() const
    {
        return m_holder == std::this_thread::get_id();
    }
#endif // #ifndef NDEBUG

private:
#ifndef NDEBUG
    std::atomic<std::thread::id> m_holder = std::thread::id{};
#endif // #ifndef NDEBUG
};

请注意以下事项:

  1. 在发布模式下,这具有零开销std::mutex除了可能的构造/销毁(这对于互斥对象来说不是问题)。
  2. The m_holder仅在获取互斥体和释放互斥体之间访问成员。因此互斥体本身充当m_holder。对类型的假设非常弱std::thread::id, locked_by_caller将正常工作。
  3. 其他标准库类型,例如std::lock_guard是模板,因此它们可以很好地与这个新类配合使用,因为它满足Mutex https://en.cppreference.com/w/cpp/named_req/Mutex要求。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何断言 std::mutex 是否被锁定? 的相关文章

随机推荐

  • 如何删除已删除的 git 子树文件夹的历史记录?

    我使用 git subtree 添加了一个 git 存储库 问题是我硬重置回使用 git subtree 添加存储库之前 现在提交历史记录仍在存储库中 但已与主服务器断开连接 知道如何删除它吗 我尝试了 git rm cached 但没有成
  • 跨多个表维护 Identity 值

    我们遇到的情况是 多个表中有一个名为 Customer Number 的列 该列是所有表中的标识列 但是有没有办法可以使该列在所有表中唯一 例如 如果我在 table one 中添加一行 并且标识列为其分配值 1 现在如果有人在 table
  • 从.ajax()调用加载knockout.js observableArray()

    这让我很困惑 这一定是我没看到的小事 我正在尝试加载一个非常简单的observableArray通过 ajax 调用进行淘汰赛 javascript we bind the array to the view model property
  • 抑制命令行输出

    我有一个像这样的简单批处理文件 echo off taskkill im test exe f gt nul pause 如果 test exe 未运行 我会收到以下消息 ERROR The process test exe not fou
  • 静态主类 - AS3

    有没有一种方法可以使主类 基于主 fla 的类 静态 所以我们可以像在java中一样使用它 能够从其他类引用它 因为我必须将main本身的实例作为参数传递给一个类 否则我会失去引用 我尝试添加静态前缀 但似乎 as3 不允许 AS3中没有静
  • 生成随机数一次

    我需要创建一组 0 到 800 之间的随机数 问题是目前我需要快速执行此操作 并且每个数字仅返回一次 我目前的做法是 创建一个std vector包含从 0 到 800 的数字 使用选择一个号码numberVector rand numbe
  • 如何正确读取 Flux 并将其转换为单个 inputStream

    我在用着WebClient和定制BodyExtractor我的 spring boot 应用程序的类 WebClient webLCient WebClient create webClient get uri url params acc
  • Blazor WebAssembly Visual Studio 调试器问题

    我创建了一个干净的 Blazor PWA 项目 当我尝试使用调试器运行它时 不到一半的时间它无法正确启动 一半的时间实际上会有所改善 如果尝试使用调试器 F5 或调试 开始调试 启动 则会打开一个新的浏览器窗口 其中 URL 为 about
  • 适用于 Swift 5 和 Facebook SDK 5 的 Facebook GraphRequest

    我最近更新了我的所有pods和快速的语言Swift 5在我的项目中 收到了大量错误消息 我已经慢慢解决了这些消息 然而 我在 Facebook 上遇到了困难GraphRequest之前工作正常 特别是此错误消息位于version的参数Gra
  • 如何将 Log4J2 复合配置与 Spring Boot 结合使用

    我使用 Spring Boot 2 0 1 starter 和 log4j2 使用以下 POM WAR 文件托管在 Tomcat 8 中 而不是使用嵌入式 tomcat 应用程序日志写入控制台而不是写入日志文件 显然 Spring Boot
  • javascript 中的 location.search 是什么

    我想知道什么location search substring 1 事实上确实如此 我在某个网站上看到了这段代码 我尝试使用打印alert 但这并没有给出任何结果 它应该提醒 location href 吗 alert location s
  • 使用 Xamarin 项目中的 netstandard13 包

    我正在尝试使 Npgsql NET 的 PostgreSQL 提供程序 可供 Xamarin 用户使用 Npgsql已经支持 NET Platform Standard 版本3 并且该标准的文档包含以下句子 如果库面向 NET Platfo
  • 在 Ruby on Rails 中,DateTime、Timestamp、Time 和 Date 之间有什么区别?

    根据我的经验 在编程时获得正确的日期 时间总是充满危险和困难 Ruby 和 Rails 在这方面一直让我困惑 只是因为有太多的选择 我从来不知道我应该选择哪个 当我使用 Rails 并查看 ActiveRecord 数据类型时 我可以找到以
  • 菜单栏隐藏时加速器停止响应

    我有一个基于空地的 gtk3 用户界面 并且我为几个菜单项设置了加速器字段 我不确定 GtkBuilder 在加载林间空地文件时到底在幕后做了什么 使用全局 GtkAccelGroup 但最终结果是 当我隐藏菜单栏时 加速器快捷键停止工作
  • 如何在Javascript中按百分比使一种颜色与另一种颜色相似

    我有两种十六进制形式的颜色 000000 and ffffff 我想按百分比将第一种颜色与第二种颜色近似 就像是 var percent 0 50 var color1 000000 var color2 ffffff var newcol
  • 与 emacs/slime 的其他 Lisp/Scheme 实现等效的 'lein swank'

    我一直在使用 emacs slime 来编码 lisp 但是使用 Clojure 我发现了 lein swank 我必须说它非常有用 因为我可以连接到运行 clojure 的服务器 其他 Lisp 实现怎么样 哪些 Lisp 实现提供了与
  • Angular2重置表单并标记为未触及

    提交后如何重置表单并标记为未触及 干净等 因为我停留在页面上并且用户可以重新提交 this myForm reset this myForm markAsPristine this myForm controls options name
  • 在 Android 上录制视频时添加叠加

    我想在我的 Android 设备中通过摄像头录制视频 我需要在录制的电影上添加叠加图像 在 iOS 中我会使用GPUImage https github com BradLarson GPUImage 在Android中我发现Android
  • Android 无法接收组播数据包

    我正在玩一点多播套接字 我编写了一个向 Android 客户端发送消息的服务器 到目前为止 客户端应该只记录收到的消息 我注意到我的设备上没有收到多播数据包 这是服务器的代码 在电脑上运行 public class MulticastSer
  • 如何断言 std::mutex 是否被锁定?

    使用 GCC 4 8 2 在 Linux Debian Sid 64 位上 或 GCC 4 9 如果可用 在 C 11 中 我有一些互斥体 std mutex gmtx actually it is a static member in s