在一篇关于c++11内存排序文章中,作者给出了一个“线程库不能在c++03中工作”的推理示例。
for (...){
...
if (mt) pthread_mutex_lock(...);
x=...x...
if (mt) pthread_mutex_unlock(...);
}
//should not have data-race
//but if "clever" compiler use a technique called
//"register promotion" , code become like this:
r = x;
for (...){
...
if (mt) {
x=r; pthread_mutex_lock(...); r=x;
}
r=...r...
if (mt) {
x=r; pthread_mutex_unlock(...); r=x;
}
x=r;这里有3个问题:
1.这是不是只破坏了c++03?What中关于c语言的互斥保护?
2.c++03线程库变得无法工作?
3.是否有其他促销活动可能导致同样的问题?
如果这是错误的例子,那么线程库是有效的,那么Hans Boehm的“thread Cannot be Implemented as a Library”又如何呢?
发布于 2018-12-28 20:26:11
POSIX函数pthread_mutex_lock和pthread_mutex_unlock是内存屏障,编译器和/或CPU不能对它们周围的加载和存储进行重新排序。否则互斥锁将是无用的。那篇文章可能是不准确的。
请参阅POSIX 4.12 Memory Synchronization
应用程序应确保限制多个控制线程(线程或进程)对任何内存位置的访问,以便当另一个控制线程可能正在修改某个内存位置时,任何控制线程都无法读取或修改该内存位置。使用同步线程执行的功能来限制这种访问,并且还相对于其他线程同步存储器。以下函数可针对其他线程同步内存:请参阅网站
上的列表
发布于 2019-01-09 03:55:25
对于单线程代码,抽象机中的状态是不可直接观察的:当您暂停具有信号的唯一线程并通过ptrace或等效物观察它时,不能保证非易失性对象具有任何特定状态。唯一的要求是程序执行具有与抽象机的一种可能执行的行为相同的可观察行为。
观察值是与外部世界的交互;基本上是流上的输入/输出和易失性对象上的动作。
单线程代码的编译器可以生成对全局变量或恰好在线程之间共享的其他对象执行操作的代码,只要遵守单线程语义即可。很明显,如果全局变量以返回原始值的方式进行更改,就会出现这种情况。
例如,编译器可能会发出递增然后递减变量的代码,至少在某些极少数情况下是这样;目标是发出简单的代码,但代价是偶尔执行几个不需要的操作。
对抽象机器中不存在的共享变量进行这样的更改,显然会破坏并发执行真实操作的多线程代码;这样的代码在访问共享变量时没有任何竞争条件,这些变量被正确序列化,但是生成的代码引入了破坏程序的竞争。
https://stackoverflow.com/questions/53955839
复制相似问题