BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #81434同步于 2014/8/9
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

[多线程毁三观]2.画蛇添足

nuanyangyang
2014/8/9镜像同步15 回复
请问下面的程序为什么有时候r1和r2的值会不一样?不要简单地说程序是未定义行为,虽然这是事实,确实有data race,确实是未定义行为,任何事都允许发生,从什么都不发生到电脑冒烟都是允许的。但能不能给出一个为什么会发生的原因呢? 需要C++11 #include <cstdio> #include <atomic> #include <thread> #include <mutex> int x; std::mutex m1, m2; void func1() { m1.lock(); x = 1; m1.unlock(); } void func2() { m2.lock(); x = 2; m2.unlock(); } void func3() { m1.lock(); m2.lock(); int r1 = x; int r2 = x; m2.unlock(); m1.unlock(); std::printf("r1 = %d, r2 = %d\n", r1, r2); } int main() { std::thread t1(func1); std::thread t2(func2); std::thread t3(func3); t1.join(); t2.join(); t3.join(); return 0; } 为了避免争议,解释一下,上述程序是错误的。这两个锁很“画蛇添足”,前两个线程可以分别加锁,中间对x根本不是互斥访问的。换句话说,线程1和线程2对x的两个写之间不存在happen-before关系,故引发data race。在C++11中,data race是未定义行为,任何事都允许发生,从什么都不发生到电脑冒烟都是允许的。
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
iFadeToBlack机器人#1 · 2014/8/9
大概是1和2的写没有立即写回内存,使对3可见 还需要查lock的实现验证一下,明天再说
a1019866208机器人#2 · 2014/8/10
Data race,膜拜暖女神 发自「贵邮」
zx723机器人#3 · 2014/8/10
个人觉得讨论这个问题的时候,不说明Consistency Model,就没法讨论了
nuanyangyang机器人#4 · 2014/8/10
【 在 zx723 的大作中提到: 】 : 个人觉得讨论这个问题的时候,不说明Consistency Model,就没法讨论了 C++11 memory model
gaoweiwei机器人#5 · 2014/8/11
暖神开个这个方面的专题帖吧,让我们学习学习 【 在 nuanyangyang 的大作中提到: 】 : C++11 memory model
nuanyangyang机器人#6 · 2014/8/11
去翻一翻Hans Boehm的论文吧,他是这方面的专家。 【 在 gaoweiwei 的大作中提到: 】 : 暖神开个这个方面的专题帖吧,让我们学习学习 来自「北邮人论坛手机版」
nuanyangyang机器人#7 · 2014/8/11
嗯。这个解释还是可以的。 不过,具体实现的可能比标准定义的严格。但除非某个实现的文档告诉你这个行为可依赖,否则还是不能依赖。 【 在 iFadeToBlack 的大作中提到: 】 : 大概是1和2的写没有立即写回内存,使对3可见 : 还需要查lock的实现验证一下,明天再说 来自「北邮人论坛手机版」
tonyjansan机器人#8 · 2014/8/11
这个程序写法太粗暴了,全局变量没初始化并且压栈、锁操作过于繁琐了。
nuanyangyang机器人#9 · 2014/8/11
【 在 tonyjansan 的大作中提到: 】 : 这个程序写法太粗暴了,全局变量没初始化并且压栈、锁操作过于繁琐了。 选自一篇论文,讨论的是一些异常情形。毕竟这个程序是错误的。有可能是从更复杂的程序里提取出来的简单代码,把中间复杂的运算抽象掉了,专门来指明错误。 不过全局变量按规定是要初始化成0的(除非有构造函数),这倒不是问题。