4
函数是否是现代平台的有效内存屏障?
在我审阅的代码库中,我发现了以下成语。 void notify(struct actor_t act) { write(act.pipe, "M", 1); } // thread A sending data to thread B void send(byte *data) { global.data = data; notify(threadB); } // in thread B event loop read(this.sock, &cmd, 1); switch (cmd) { case 'M': use_data(global.data);break; ... } 我对我的团队的资深成员对作者说:“保存”,这里没有内存屏障!您不保证global.data将其从缓存刷新到主内存。如果线程A和线程B将在其中运行两个不同的处理器-此方案可能会失败”。 高级程序员咧嘴笑着,慢慢地解释,好像在解释他的五岁男孩如何系鞋带:“听小男孩,在高负载测试和实际客户中,我们在这里看到了许多与线程相关的错误”,他停下来挠挠他长长的胡须,“但是这个习语从来没有犯过错误”。 “但是,它在书中说……” “安静!”他迅速向我嘘声,“也许从理论上讲不能保证,但实际上,您使用函数调用的事实实际上是内存障碍。编译器不会对指令进行重新排序global.data = data,因为它不知道是否任何在函数调用中使用它的人,x86架构将确保在线程B从管道读取命令时其他CPU将看到此全局数据,请放心,我们有很多现实问题需要担心。我们不需要在虚假的理论问题上投入额外的精力。 …