虚假唤醒后的互斥状态

2023-11-30

考虑这个使用 pthread 的基本多线程程序。 我们有一个主线程,创建另一个执行一些工作的线程。

bool done = false;
mutex m; 
condition c;

void foo() {
    pthread_mutex_lock(&m);
    //while(!done) {
        pthread_cond_wait(&c, &m);
        // Spuriously wakeup while child is doing work.
        // child thread has NOT unlocked the mutex yet
        // Do I now own the mutex?
        // or am I waiting for child to unlock it?
    //}
    pthread_mutex_unlock(&m);
}

void * child(void *arg) {
    pthread_mutex_lock(&m);

    some_intense_work(); // this work is done while mutex is held!
    // the main thread spuriously wakes up
    // while this work is being done
    // (while this child thread is holding the mutex)

    done = true;
    pthread_cond_broadcast(&c);
    pthread_mutex_unlock(&m);
}

int main(int argc, char *argv[]) {
    pthread_t p;
    pthread_create(&p, NULL, child, NULL);
    foo();
}

假设我们实现了等待,但没有周围的 while 子句检查谓词,即使我们知道没有人应该这样做。

现在,如果当子线程正在执行其工作时,主线程中发生虚假唤醒,则互斥体 m 的状态将是什么?主线程是否会在子线程先解锁它的情况下拥有它,以便双方都拥有它?

或者虚假唤醒是否仅跳过对条件的等待,而不是对互斥体被释放的等待?


The pthread_cond_wait()当其他线程持有关联的互斥锁时,调用无法“虚假”唤醒。什么时候pthread_cond_wait()成功返回,它将声明该互斥锁,因此在互斥锁可用之前它无法成功返回。

在您的示例中,可能会发生虚假唤醒,因为foo()可以打电话pthread_cond_wait()并让虚假唤醒发生在child()有机会打电话pthread_mutex_lock()首先。

您的示例中的另一个问题(注释代码被禁用)是可能的pthread_cond_wait()拨电至never唤醒。这种情况可能会发生,如果child()之前完成所有处理foo()设法获取互斥体。在那种情况下,child()将会通知pthread_cond_broadcast()在主线程等待之前pthread_cond_wait()所以主线程会错过广播。自从foo()从不检查done当持有互斥体时,它不会注意到child()已经完成了它的工作。

这就是为什么pthread_cond_wait()几乎总是必须在检查条件的循环中执行。

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

虚假唤醒后的互斥状态 的相关文章

  • 我的线程图像生成应用程序如何将其数据传输到 GUI?

    Mandelbrot 生成器的缓慢多精度实现 线程化 使用 POSIX 线程 Gtk 图形用户界面 我有点失落了 这是我第一次尝试编写线程程序 我实际上并没有尝试转换它的单线程版本 只是尝试实现基本框架 到目前为止它是如何工作的简要描述 M
  • 以编程方式检查页面是否需要基于 web.config 设置进行身份验证

    我想知道是否有一种方法可以检查页面是否需要基于 web config 设置进行身份验证 基本上如果有这样的节点
  • C# 中的接口继承

    我试图解决我在编写应用程序时遇到的相当大的 对我来说 问题 请看这个 为了简单起见 我将尝试缩短代码 我有一个名为的根接口IRepository
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 对齐 GridView 中的行值

    我需要在 asp net 3 5 中右对齐 gridview 列中的值 我怎样才能做到这一点
  • JSON 数组到 C# 列表

    如何将这个简单的 JSON 字符串反序列化为 C 中的列表 on4ThnU7 n71YZYVKD CVfSpM2W 10kQotV 这样 List
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • strcmp 给出分段错误[重复]

    这个问题在这里已经有答案了 这是我的代码给出分段错误 include
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 我在在线程序挑战编译器中遇到演示错误

    include
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐

  • 将 lambda 参数传递给 include 语句

    我正在使用System Data Entity命名空间 因此我可以将 lambda 表达式传递给 Linq Include 方法 public ICollection
  • 容器绑定脚本尝试从侧边栏使用 google.script.run 运行函数时出现权限错误

    我尝试在电子表格上实现侧边栏 以获取用户输入以供我的脚本使用 我无法让它成功调用任何服务器端函数 我将谷歌文档中的一个简单脚本和我读过的几个 stackoverflow 问题放在一起 但我不断收到错误 它能够打印到控制台 但尝试调用时出错日
  • Eclipse 中的 Boost 链接错误

    我一直在尝试将 boost 的线程功能包含在 Ubuntu 上的 Eclipse C 项目中 但毫无结果 到目前为止的步骤 从 boost org 下载 boost configure with libraries system threa
  • 如何正确获取使用 flex-direction:column 显示的块的实际宽度?

    例如 HTML console log container width 600px as we defined in css console log list width 600px console log box eq 1 positio
  • read() 系统调用实际读取的数据量

    假设我有一个文件 其文件描述符在 EOF 之前剩余的字节数超过 n 个字节 并且我调用了 n 个字节的 read 系统调用 该函数是否保证将 n 个字节读入缓冲区 还是可以少读点 The read系统调用保证读取您所要求的尽可能多的字符 除
  • JS:循环遍历div列表以通过onclick添加事件?

    div test div div test div div test div 如果我有一个 div 列表 并且希望在单击每个 div 时将字体大小增加到 20px 我知道我可以执行以下操作 let elements document que
  • SOLR旅游网站:关于日期查询

    我正在寻找为酒店预订网站实施 SOLR 根据位置 酒店名称 设施进行的搜索非常有效 分面也是如此 我不知道如何在给定入住和退房日期的情况下搜索酒店 例如 用户将搜索搜索查询 纽约的酒店 然后从日期选择框中选择入住日期 2012 年 2 月
  • 从非 constexpr 参数创建 constexpr 数组

    我从中学到了here that args不是一个常量表达式 Now 我的问题是 我应该在给定的程序中修改什么 以便我能够在第一个变体中拥有 static assert 而不会出现编译时错误 在下面的代码中 include
  • 如何在 C# 中使用派生类型重写泛型方法

    我有以下课程 public interface IService void ApplyChanges
  • 每次当我的应用程序从后台进入前台时,都会显示 IOS Default.png [重复]

    这个问题在这里已经有答案了 我是IOS开发新手 我设置了一个 Default png 文件 每次应用程序从后台进入前台时都会显示它 但我只想在应用程序启动时显示一次 Default png 我观察到 每当应用程序从后台恢复时 iOS 5 0
  • 为什么我们在“==”比较中指定变量的顺序很重要?

    我注意到 仅更改与 运算符进行比较的变量的顺序就会产生很大的性能差异 例如 variable variable 比variable variable 慢得多 为什么会这样 有类似的案例吗 顺便说一下 我使用的是从 GitHub 下载的 Op
  • 如何在 PowerShell 中从连接字符串获取数据库名称

    我正在尝试从 PowerShell 中的连接字符串获取数据库名称 Server server instance uid User pwd Hello Database SomeName 我可以想到两种方法来做到这一点 要么搜索字符串Data
  • 作曲家在 PHP 中未找到类异常

    我正在尝试包含来自作曲家的包 但我收到了找不到类 error 我已经尝试过以下可能性 supermeteor new Supermeteor Supermeteor XXXXXXXX and use Supermeteor Supermet
  • 如何将句子中第一个单词的第一个字母大写?

    我正在尝试编写一个函数来清理用户输入 我并不想让它变得完美 我宁愿有几个小写的名字和缩写 也不愿有一个完整的大写段落 我认为该函数应该使用正则表达式 但我对这些非常不熟悉 我需要一些帮助 如果以下表达式后跟一个字母 我想将该字母设为大写 f
  • 仅选择一个选项在角度4中显示ID而不显示名称

    我正在研究 Angular 4 Web API 当选择一个选项时 它将显示打包类型名称 其工作正常 但我的问题是 当单击添加按钮时 它只会保存我想要的包装类型ID 包装类型ID 和包装类型名称 这里我想在选择包装类型名称时自动将其ID 传递
  • 如何检测具有背景模糊的容器的亮度以改变文本的颜色

    模糊容器的亮度根据背景中的图像而变化 有没有办法检测图像或模糊容器的亮度来改变文本颜色 最好不处理图像 我制作了一个小部件作为一个有趣的练习和概念验证 称为PixelDataOverlay 它有一个background建设者和overlay
  • 二进制与线性搜索未排序的 N 个元素

    当我们应该使用快速排序时 我尝试理解一个公式 例如 我们有一个数组N 1 000 000元素 如果我们要搜索只有一次 我们应该使用一个简单的线性搜索 但如果我们要做 10 次 我们应该使用排序数组O n log n 如何检测阈值 何时以及对
  • 批处理窗口中的正则表达式

    我目前正在处理批处理作业 我也是新手 以获取 Maven 依赖项列表 一直在努力使用正则表达式获取这些依赖项 但无济于事 我已经对此测试了我的正则表达式site看起来它正在发挥作用 从这里检查了 FOR 循环内所需的转义字符堆栈溢出问题但同
  • 如何在 if 语句中使用这个布尔值?

    private String getWhoozitYs StringBuffer sb new StringBuffer boolean stop generator nextBoolean if stop true sb append y
  • 虚假唤醒后的互斥状态

    考虑这个使用 pthread 的基本多线程程序 我们有一个主线程 创建另一个执行一些工作的线程 bool done false mutex m condition c void foo pthread mutex lock m while