:就为了一个原子操作,其他CPU核心罢工了

i++问题
“阿Q赶快回去吧 , 隔壁二号车间的虎子说我们改了他们的数据 , 上门来闹事了”
由于老K的突然出现 , 我不得不提前结束与小黑的交流 , 赶回了CPU一号车间 。
见到我回来 , 虎子立刻朝我嚷嚷:“你们是怎么回事?才几纳秒的时间 , 就把数据给我改了 , 你说这事怎么办吧!”
我听着迷迷糊糊的 , 连连说到:“虎子你先别急 , 我刚回来 , 到底出什么事儿了 , 先让我了解清楚好不好?”
:就为了一个原子操作,其他CPU核心罢工了
文章图片

文章图片

接下来 , 老K把事情的经过告诉了我 。原来 , 我们两个CPU车间各自负责的线程都在执行一个i++的操作 , 我们都把i的值放到了自己的缓存中 , 完了之后都没有通知对方 , 加了两次但结果却只有一次 , 出现了数据不一致问题 。
原子操作
了解清楚事情的原委之后 , 我向虎子说道:“大家都执行一样的代码 , 这事儿也不能怪我们啊”
虎子一听急了 , “怎么不怪你们了 , 我们比你们先一步找内存拿走了i , 那你们得等我们加完之后再用啊 , 不信你可以打电话问内存那家伙 , 看看是不是我们二号车间先来的”
“好好好 , 你先冷静一下 , 你看我们又不知道你们先去拿了 , 这不情有可原吗 , 再说现在事情已经出了 , 我们应该一起坐下来想个办法避免以后再次出现这种问题 , 你说是不是?”
虎子叹了口气问道:“那你说说你有什么办法?”
:就为了一个原子操作,其他CPU核心罢工了
文章图片

文章图片

我继续说道:“你看啊 , 像咱们在执行i++这种操作的时候就不应该被干扰”
“不被干扰?”
“对 , 比如虎子你们二号车间在访问i的时候 , 我们一号车间就不能访问 , 需要等着 , 等你们访问完成我们再来 , 非常简单的办法却很有用”
虎子听完一愣 , “这不就是加锁吗?你是想怪程序员做i++前没有加锁?”
“的确是加锁 , 不过这种简单操作还要程序员来加锁那也太麻烦了 , 咱们CPU内部处理好就行了”
“内部处理 , 你打算怎么实现?” , 虎子问到 。
“这 ,, 让我想想···” , 虎子问到了具体实现 , 我倒还没想到这一步 。
这时 , 一旁的老K站了出来:“我倒是有个办法 , 可以找总线主任啊 , 他是负责协调各个车间使用系统总线访问内存的总指挥 , 让他在中间协调一下应该不难”
老K一语点醒梦中人 , 接着我们就去找了总线主任 , 后来我们商量出了一套解决方案:我们定义了一个叫原子操作的东西 , 表示这是一个不可切分的动作 , 谁要执行原子操作 , 总线主任就在系统总线上加上一个LOCK#信号 , 其他车间的想去访问内存就得等着 , 直到原子操作指令执行完毕 。
:就为了一个原子操作,其他CPU核心罢工了
文章图片

文章图片

我们把这套方案上报了领导 , 很快就批下来了 , 后面我们8个车间都按照这套方案来工作 , 以后程序员们把i++这样的动作换成原子操作后 , 问题就能迎刃而解 。
不过施行了一段时间之后 , 各个车间却开始大倒苦水:就因为某个车间要执行一个原子操作 , 就让总线主任把系统总线锁住 , 其他车间的人都没法访问内存 , 都干不了活了 , 严重影响工作效率 。
抱怨归抱怨 , 在没有更好的替代方案出现之前 , 日子还得过下去 。
缓存引发的问题
不过 , 没过多久 , 数据不一致问题又一次出现了 。
这一次 , 倒不是加法的问题 , 我们两车间还是因为各自缓存的原因 , 先后修改了变量的值 , 对方没有即时知道 , 误用了错误的值 , 以致酿成大错 。


推荐阅读