请考虑以下算法,该算法可同时在多个线程上运行:
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;
}
}
cache
和results
都是线程之间的共享变量。如果此算法按原样运行,而没有同步,则可能发生哪种错误?如果两个线程试图同时写入cache[z]
或results[z]
,数据是否可能丢失或丢失,并且简单的数据将被赢得“竞争条件”的线程接受?
一个更具体的问题示例:假设线程A和线程B都尝试同时将数字1000写入cache[10]
,同时线程C尝试读取数据在cache[10]
中。可以断断续续地说,线程C的读取操作是否可以完成,100
,然后线程C将继续处理错误的数据?
用例:我问这个问题的现实用例是散列表缓存。如果所有线程都将使用相同的哈希表缓存,并且将在它们之间读取和写入数据,如果它们写入特定键的数据始终是相同的,我是否需要同步这些读取和写入操作?
答案 0 :(得分:1)
没人知道。不同的语言,编译器,CPU,平台和线程标准可以完全不同的方式处理此问题。任何人都无法知道将来的某些编译器,CPU或平台可能会做什么。除非语言或线程标准的文档或规范说明在这种情况下会发生什么,否则绝对没有办法知道会发生什么。当然,如果您使用的某种东西在这种情况下保证了特定的行为,那么一定会发生的事情会发生(除非它被破坏了)。
一次,不存在任何CPU可以缓冲写操作,以使它们可以无序显示。但是,如果您以这样的假设写代码,那就是写永远不会变得无序可见,那么该代码将在几乎每个现代平台上被破坏。
这个悲惨的故事一遍又一遍地重复着人们从未期望过的编译器优化,但是人们后来却期望编译器进行优化。我想到了一些混叠的壁画。
做出要求您正确想象未来计算发展的决策似乎是极不明智的,并且过去曾屡屡失败,有时甚至是灾难性的失败。