假设我有一些使用共享内存的多线程程序,其中多个线程随机覆盖一些多字节变量(例如int或double)的值,有时会相互碰撞(即.a)。(一种竞赛条件),并在随机时间从相同的变量读取值。
假设所有线程总是将相同的值写入内存地址(例如,每个线程都执行x = 1000) --如果一个线程在另一个线程正在/正在覆盖它的确切时刻读取该变量,那么是否保证具有正确的值?还是内存是否被随机覆盖?
也就是说,如果所有线程总是写x = 1000,那么线程可以读取x并得到1000以外的东西吗?
发布于 2021-01-12 00:22:52
C标准允许实现,这些实现可以提供比它授权的更低的保证。因此,该标准向后弯曲,以避免要求实现维护其成本有时可能超过其效益的任何担保,而留下如何和何时维护其收益将超过成本的保证的问题,作为标准管辖范围以外的实施质量。
尽管似乎应该不需要花费任何代价来保证使用它已经包含的值编写对象不会产生任何效果,但维护这样的保证有时需要进行一些可能有用的优化。作为一个简单的例子,请考虑以下函数
volatile zz;
unsigned test(unsigned *p, unsigned *q)
{
unsigned temp;
*p = 0x1234;
temp = *q;
zz = 1;
do {} while(zz);
*p = 0x1235;
return temp;
}在一些平台上,包括原始的8088/8086,处理代码最有效的方法可能是用*p替换最后一次分配给*p += 1;,然后使用inc指令进行处理。但是,如果代码同时在两个线程中执行,则可能导致*p保留值0x1236。
在许多情况下,维护以其已经包含的值编写对象的保证将无需花费任何费用,而将涉及此类写入的争用条件视为良性则会消除一些可能变得不必要的同步操作的成本。不幸的是,虽然标准允许实现提供超出标准要求的保证,但这样做是实用和有用的,但它没有提供将提供此类保证的实现与不提供此类保证的实现区分开来的方法。
发布于 2021-01-11 23:14:43
假设所有线程总是将相同的值写入内存地址(例如,每个线程执行
x = 1000) --如果线程在另一个线程正在/正在覆盖它的确切时刻读取变量,则是保证具有正确值?的变量。
C语言规范明确拒绝通过声明包含种族条件的程序的行为来提供这样的保证。而且,如果没有同步,您所描述的情况是一种争用状态,尽管正在写入的值是否相同是内存的初始内容。
或者内存是否会被随机的东西覆盖?
行为是未定义的。原则上,任何事情都可能发生,包括读取一个从未存储在所述位置的值。
还要注意的是,比赛不是关于任何一种客观的同时。相反,正是由于缺乏同步,才会阻止同步访问,而不管是否实际发生了任何同步访问。
在实践中,您可能会发现,在某些实现上,至少在某些情况下,不更改内存内容的写操作就好像它们之间没有冲突一样,或者在首次将该值写入位置之后发生的读取,其中“发生后”是一个技术术语,部分取决于同步。然而,我不建议依赖于这种行为。即使它被记录下来也不会。
https://stackoverflow.com/questions/65675736
复制相似问题