什么时候需要条件变量,互斥锁还不够吗?

2023-12-06

我确信互斥锁还不够,这就是条件变量概念存在的原因;但这让我很困惑,当条件变量至关重要时,我无法用具体的场景说服自己。

条件变量、互斥锁和锁之间的区别问题的接受答案说条件变量是

带有“信号”机制的锁。当线程需要时使用它 等待资源变得可用。线程可以在 CV 上“等待” 然后资源生产者可以向变量发出“信号”,其中 如果等待 CV 的线程收到通知并可以继续 执行

我感到困惑的是,线程也可以等待互斥锁,当它收到信号时,仅仅意味着该变量现在可用,为什么我需要条件变量?

P.S.:此外,无论如何,都需要互斥锁来保护条件变量,这会让我的视野更加偏向于看不到条件变量的用途。


尽管您可以按照您所描述的方式使用它们,但互斥体并不是设计用作通知/同步机制。它们旨在提供对共享资源的互斥访问。使用互斥体来发出条件信号是很尴尬的,我想看起来像这样(其中 Thread1 由 Thread2 发出信号):

Thread1:

while(1) {
    lock(mutex); // Blocks waiting for notification from Thread2
    ... // do work after notification is received
    unlock(mutex); // Tells Thread2 we are done
}

Thread2:

while(1) {
    ... // do the work that precedes notification
    unlock(mutex); // unblocks Thread1
    lock(mutex); // lock the mutex so Thread1 will block again
}

这有几个问题:

  1. 线程 2 无法继续“执行通知之前的工作”,直到线程 1 完成“通知之后的工作”。通过这种设计,Thread2 甚至没有必要,也就是说,为什么不将“之前的工作”和“通知之后的工作”移到同一个线程中,因为在给定时间只有一个可以运行!
  2. 如果 Thread2 无法抢占 Thread1,则 Thread1 在重复 while(1) 循环时将立即重新锁定互斥锁,并且 Thread1 将继续执行“通知后的工作”,即使没有通知。这意味着您必须以某种方式保证 Thread2 将在 Thread1 之前锁定互斥体。你是怎样做的?也许通过睡眠或其他一些特定于操作系统的方式强制调度事件,但即使这样也不能保证有效,具体取决于时间、操作系统和调度算法。

这两个问题都不是小问题,事实上,它们都是主要的设计缺陷和潜在的错误。这两个问题的根源在于互斥体需要在同一线程内锁定和解锁。那么如何避免上述问题呢?使用条件变量!

顺便说一句,如果您的同步需求非常简单,您可以使用普通的旧信号量,这样可以避免条件变量的额外复杂性。

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

什么时候需要条件变量,互斥锁还不够吗? 的相关文章

随机推荐

  • 时间列应使用什么数据类型

    在我的 Spark 应用程序中 我必须拆分时间和数据并将它们存储在单独的列中 如下所示 val df5 df4 withColumn read date date format df4 col date yyyy MM dd withCol
  • 在 R 中安装旧包时出错

    我正在尝试安装 0 6 2 版本的 tm 库 我已经从以下位置下载了 tar gz 文件archive并在 RStudio 中选择 工具 gt 存档 gt 打包存档文件 来安装它 但是 我收到以下错误 有人可以帮我解决这个问题吗 安装sou
  • 如何在 AWS Elastic Beanstalk 上运行 celery Worker?

    版本 姜戈 1 9 8 芹菜 3 1 23 django celery 3 1 17 Python 2 7 我正在尝试在 AWS Elastic Beanstalk 上运行我的 celery 工作线程 我使用 Amazon SQS 作为 c
  • 在头文件中声明一个返回二维数组的函数?

    我试图在我的头文件中声明一个返回二维数组的函数 鉴于我们已经知道数组的大小 如何实现这一点 以下是我目前正在做的事情 class Sample public char x y getArr void blah int x int y pri
  • PowerShell 输出的颜色重定向到文件

    dir颜色输出到文件 如果我在 Ubuntu 上运行以下命令 dharmatech dharmatech 01 tmp pwsh Command dir gt out txt 然后 cat 输出 dharmatech dharmatech
  • 周数和周日

    我有由 date 生成的当年周数和星期几 如下所示 week number date W week day date w 我需要格式化这个 我如何获得本周的开始日期 或者 week number 和 week day 是一个月中的哪一天 U
  • 如何通过最新的 Android 支持库正确使用向后兼容的 Vector Drawable?

    Vector Drawable 不久前已添加到支持库中 从那时起 API 发生了很多变化 Gradle 标志 初始化块 选择器 自定义 XML 属性等 问题是 现在如何正确使用它 在这些情况下支持 lib v25 图像视图 可绘制的文本视图
  • 如何实现 PHP/HTML 缓存

    我读过几本关于实现 php 缓存系统的指南 我的网站是自定义编码的 查询量相当大并且不断增长 包括这个 http www snipe net 2009 03 quick and dirty php caching 我完全理解它们 但页面的某
  • 无法在 Windows 10 Pro 上启动 docker?

    Problem 当我尝试启动 docker 桌面时 它给我留下了这个错误 Unable to create The running command stopped because the preference variable ErrorA
  • .NET 客户端通过 SSL 连接到 IBM MQ

    我从客户端获得了密钥文件 我需要使用它们通过 SSL 连接到 MQ 我们从客户那里得到的文件是 xxx crl xxx kdb xxx rdb xxx sth xxx tab 他们说的是客户端频道表 我正在尝试使用以下代码进行连接 他们说我
  • 将 UTC 日期时间字符串转换为本地日期时间

    我从来没有需要在 UTC 和 UTC 之间进行时间转换 最近有人请求让我的应用程序了解时区 但我一直在兜圈子 有关将本地时间转换为 UTC 的大量信息 我发现这些信息相当简单 也许我也做错了 但我找不到任何有关轻松将 UTC 时间转换为最终
  • 如何在C#中访问匿名类型的属性?

    我有这个 List nodes new List nodes Add new Checked false depth 1 id div d Id 我想知道是否可以获取匿名对象的 Checked 属性 我不确定这是否可能 尝试这样做 if n
  • 如何在 Angular 2 上实现自定义验证器?

    如何在 Angular 2 中实现自定义验证器 I found 这个笨蛋 constructor private fb FormBuilder this form fb group singleSelection Rio App valid
  • 为什么 C 应用程序不先打印消息然后接收用户输入

    我正在尝试编写一个打印提示并接受用户输入的 C 应用程序 我用 fgets 编写了一个简单的程序 但它确实工作正常 我正在使用 eclipse c c 工具包 当我保存 gt 构建 gt 运行时 控制台保持空白 如果我输入一些输入 程序就会
  • apc vs eaccelerator vs xcache

    我正在研究使用其中哪一个 但我真的找不到一个脱颖而出的 E加速器比APC 但APC维护得更好 Xcache更快 但其他的语法更简单 有人对使用哪些建议以及为什么使用有建议吗 APC 将包含在 PHP 6 中 我猜选择它是有充分理由的 它的安
  • vector.push_back 上的“glibc free():无效的下一个大小(快速)”?

    当我运行我的程序时 它偶尔会崩溃并给出以下错误 检测到 glibc pathtoexecutable free 下一个大小无效 快速 回溯导致一个成员函数只调用向量的push back函数 void Path add Position p
  • 用于将重复行插入另一个表的插入触发器之前

    我有一张桌子叫tblspmaster其中 sp 列我有唯一索引 因此不会插入重复项 但我想将重复行插入到tblspduplicate 所以我决定为此编写触发器 IN 主表是tblspmaster记录将使用加载文件插入mysql create
  • 条形图上的错误栏

    我试图得到 一个漂亮的组条形图 我希望每个条形上都有误差条 如下所示 或类似的 由您自行决定 我有办法 ff Medical eq Patient Hygiene Near bed Far bed Direct 1 2759 0 9253
  • 为什么我的 XML 阅读器读取所有其他元素?

    我构建了一个非常简单的表格 显示 4 列和 4 行 执行以下代码时 它会显示 xml 文件中的所有其他元素 它不区分每个表行 它读起来没有任何问题 而且我已经运行了 xml 验证器 所以这不是语法问题 public partial clas
  • 什么时候需要条件变量,互斥锁还不够吗?

    我确信互斥锁还不够 这就是条件变量概念存在的原因 但这让我很困惑 当条件变量至关重要时 我无法用具体的场景说服自己 条件变量 互斥锁和锁之间的区别问题的接受答案说条件变量是 带有 信号 机制的锁 当线程需要时使用它 等待资源变得可用 线程可