condition_variable.notify_all 是否应该被互斥锁覆盖?

2023-11-24

我已经实现了一个类,它允许我将线程与条件变量同步。我发现关于 notify_all 应该在锁内还是在锁外完成的冲突信息。我发现了两种方式构建的例子。

首先释放锁的理由是为了防止等待线程在被通知释放后立即阻塞在互斥锁上。

反对首先释放锁的论点是等待线程可能会错过通知。

两个版本的release函数在这里:

// version 1 - unlock then notify.
void release(int address = 1)
{
    {
        std::lock_guard<std::mutex> lk(_address_mutex);
        _address = address;
    }
    _cv.notify_all();
}

// version 2 - notify then unlock
void release(int address = 1)
{
    std::lock_guard<std::mutex> lk(_address_mutex);
    _address = address;
    _cv.notify_all();
}

作为参考,等待代码如下所示:

bool wait(const std::chrono::microseconds dur, int address = 1)
{
    std::unique_lock<std::mutex> lk(_address_mutex);
    if (_cv.wait_for(lk, dur, [&] {return _address == address; }))
    {
        _address = 0;
        return true;
    }
    return false;
}

在版本 1 中,允许互斥锁在 notification_all 之前超出范围,等待线程是否存在丢失通知的风险?如果是这样,它是如何发生的? (我不清楚这如何导致错过通知。)

我可以清楚地看到在通知期间保持互斥体锁定如何导致等待线程立即进入等待状态。但如果它能防止错过通知,这只是一个很小的代价。


没有释放锁的风险if互斥锁在条件测试状态更改和 thr 通知之间的某个时间间隔内保持。

{
    std::lock_guard<std::mutex> lk(_address_mutex);
    _address = address;
}
_cv.notify_all();

在这里,互斥体在之后被解锁_address被改变了。所以没有风险。

如果我们修改_address为了成为原子的,天真地这看起来是正确的:

{
    std::lock_guard<std::mutex> lk(_address_mutex);
}
_address = address;
_cv.notify_all();

但事实并非如此;在这里,互斥量在修改条件测试和通知之间的整个期间被释放,

_address = address;
{
    std::lock_guard<std::mutex> lk(_address_mutex);
}
_cv.notify_all();

然而,上面的内容又变得正确了(虽然有点奇怪)。


风险在于条件测试将在互斥体处于活动状态(为假)的情况下进行评估,然后进行更改,然后发送通知,then等待线程等待通知并释放互斥体。

waiting|signalling
lock
test
        test changed
        notification
listen+unlock

以上是错过通知的示例。

只要我们在测试更改之后和通知之前将互斥体保存在任何地方,就不会发生这种情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

condition_variable.notify_all 是否应该被互斥锁覆盖? 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • ctc_loss 错误“未找到有效路径。”

    训练模型tf nn ctc loss每次运行训练操作时都会产生错误 tensorflow core util ctc ctc loss calculator cc 144 No valid path found 与之前有关此函数的问题不同
  • 我可以在没有本地副本的情况下在远程存储库上发出 git rev-parse 吗?

    我的本地 git 存储库位于加密卷内 我希望能够跑步git pull all仅当远程有新提交时 但是 我无法使用像这样的接收后钩子here因为我没有加密卷的密码 这意味着即使钩子被触发 我仍然不知道安装卷和提取新更改的密码 所以我正在寻找其
  • 精度损失 - int -> float 或 double

    我有一道考试题正在复习 题目为 4 分 在java中 我们可以将int分配给double或float 这会丢失信息吗 为什么 我这样说是因为整数通常具有固定的长度或大小 存储数据的精度是有限的 而以浮点存储信息可以是无限的 本质上我们会因此
  • 如何为 Symfony2 中的所有控制器添加一些路由前缀?

    我使用注释来定义控制器中的路由 并且我有 15 个控制器 全部由执行 path1 path2 有什么方法可以在所有这些控制器中通过以下方式访问它们 admin path1 and admin path2 我不想通过更改每个文件来输入它 我可
  • 与数据表进行数据绑定后,GridView Column.Count 始终为 0

    我正在尝试有条件地显示 隐藏 GridView 列 我正在创建一个动态 DataTable 然后将其绑定到 GridView 后来 在回发时 我正在检查条件并想要显示 隐藏 GridView 的几列 但 Column Count 始终为 0
  • 如何使用 PyQt5 在同一窗口中更改 UI?

    我刚刚开始使用 PyQt5 我一直在尝试完成一项看似非常简单的任务 但无法获得足够的信息 经过一番谷歌搜索后 我已经能够关闭一个窗口 并在加载另一个 UI 的情况下启动另一个窗口 但这不是我想要在这里做的 我想在同一个窗口中切换用户界面 我
  • 如何使用 Swing 创建可扩展面板?

    我想创建一个展开和折叠面板的列表 如下图所示 我还没有找到任何与此相关的 Swing 组件 所以我开始创建类似的东西 我尝试将按钮一个放在另一个下面 以填充可用宽度 但实际上不起作用 我只能看到最后添加的一个 JPanel panel ne
  • Xcode Instruments 8.3 显示设置按钮丢失

    在最新版本的 Instruments 8 3 中 显示设置按钮已被删除 并由文件 gt 记录设置对话框取代 使用分配工具时 我现在无法再激活自动快照 因为该选项已从右侧面板中消失 并且记录选项对话框仅显示分配工具的值 而不显示虚拟机跟踪器的
  • 如果数学移至内联函数,为什么 C++ 舍入行为(对于编译时常量)会发生变化?

    考虑以下函数 static inline float Eps const float x const float eps std numeric limits
  • 如何关闭 Eclipse 上的项目方面?

    我试图解决 Eclipse 中的问题 所以我单击了 Propreties gt Project Facets gt Click on the link 现在我有了新的看法Project Facets还有很多错误 我不知道如何返回上一步并取消
  • 核心数据,一对多子对象排序

    所以 假设我有一个父母孩子的商店 父母与孩子有一对多的关系 parent children 并且他们都有名字 现在 在初始获取父母时 我可以指定一个排序描述符以按名字顺序返回它们 但是如何按顺序请求孩子呢 如果我执行 parent chil
  • 如何让TextBox失去焦点?

    怎么做TextBox当用户触摸时失去焦点并隐藏屏幕键盘Enter虚拟钥匙 private void TheName KeyDown object sender KeyRoutedEventArgs e var tb sender as Te
  • Android:连接并打印到 Bixolon SPP-R200

    我想打印到Bixolon SPP R200据我所知 它是更容易使用 Android 设置的移动蓝牙打印机之一 但是我不知道如何开始 我想首先我必须通过蓝牙连接到打印机 我假设为此目的我求助于本机 Android 蓝牙 API 我可能需要某种
  • Rails 3.1:accepts_nested_attributes_for 和 has_one 关联 - 不起作用?

    我试图在 has one 关联模型上使用 Accepts nested attributes for 但绝对无处可去 我有两个模型 一个用户和一个位置 一位用户有一个位置 class User lt ActiveRecord Base cu
  • 登录管理页面后,Django 服务器立即停止

    单击登录按钮后立即尝试登录 django 管理页面 django 服务器停止 Django 新手尝试使用 venv 在虚拟环境中创建项目 这些是我所做的以下步骤 1 创建一个名为api的文件夹 2 使用创建虚拟环境python m venv
  • 使用 Linq to Entities 在一项操作中获取 COUNT 和 SKIP TAKE

    我在 Linq to Entities 支持的数据访问层中有一个数据调用 该数据访问层旨在进行分页调用 在此过程中 我需要选择数据的子集 例如 50 行 但还要获取所有匹配项的计数 以了解需要分页的总匹配项数 目前 我正在执行以下操作 va
  • “+”、“*”、“!”是什么意思?分支名称旁边的符号在 VS Code 中表示吗?

    在 VS Code 中有一个 在我的分行名称旁边签名 这意味着什么 检查源代码揭示 表示您有未暂存的更改 尚未添加 表示您已分阶段进行更改 已添加 但未提交 表示未合并的冲突 还可以有Rebasing 在最后 当你处于变基过程中时 所以 如
  • LINQ: ...Where(x => x.Contains(以“foo”开头的字符串))

    给定以下类的集合 public class Post public IList
  • 使用 python 导入我的数据库连接

    是否可以使用我的数据库凭据创建一个 py 文件来连接到 MySQL 数据库 Ex con ip 0 0 0 0 username root password pswd database test 然后在另一个文件上使用这个文件 like i
  • condition_variable.notify_all 是否应该被互斥锁覆盖?

    我已经实现了一个类 它允许我将线程与条件变量同步 我发现关于 notify all 应该在锁内还是在锁外完成的冲突信息 我发现了两种方式构建的例子 首先释放锁的理由是为了防止等待线程在被通知释放后立即阻塞在互斥锁上 反对首先释放锁的论点是等