在多线程环境中,我是否需要同步来读取和写入通用缓存文件



考虑以下算法,该算法同时在多个线程上运行:

for (i=0; i<10000; i++) {
z = rand(0,50000);
if (isset(cache[z])) results[z] = cache[z];
else {
result = z*100;
cache[z] = result;
results[z] = result;
}

}

CCD_ 1和CCD_ 2都是线程之间的共享变量。如果这个算法按原样运行,没有同步,会发生什么样的错误?如果两个线程试图同时写入cache[z]results[z],数据会丢失吗?还是简单明了的数据会被赢得"竞争条件"的线程接受?

问题的一个更具体的例子是:假设线程A和线程B都试图同时向cache[10]写入数字1000,同时线程C试图读取cache[10]中的数据。线程C的读取操作是否可以在间歇状态下完成,比如说,作为100,然后线程C将继续使用不正确的数据?

用例:我要问的一个现实生活中的用例是hashtabled缓存。如果所有线程都将使用相同的哈希表缓存,并且它们将从中读取数据和向中写入数据,如果它们写入特定密钥的数据始终相同,我需要同步这些读取和写入操作吗?

没人可能知道。不同的语言、编译器、CPU、平台和线程标准可以以完全不同的方式处理这一问题。任何人都无法知道未来的编译器、CPU或平台可能会做什么。除非语言或线程标准的文档或规范说明在这种情况下会发生什么,否则绝对无法知道可能会发生什么。当然,如果在这种情况下,你使用的东西保证了特定的行为,那么保证会发生的事情就会发生(除非它坏了)。

曾经,不存在任何缓冲写操作的CPU,因此它们可能会无序可见。但是,如果你在这样的假设下编写代码,即这意味着写的东西永远不会无序可见,那么几乎所有现代平台上的代码都会被破坏。

这个悲伤的故事一次又一次地重复着许多编译器优化,人们从来没有想过编译器会做出这些优化,但编译器后来做出了这些优化。脑海中浮现出一些混叠的惨败。

做出需要你正确想象未来可能的计算进化的决定似乎是极不明智的,而且在过去曾多次失败,有时甚至是灾难性的。

最新更新