Ruby 问一个问题。Fixnum 中 += 和 -=是原子操作吗?有没有源码地址呢?

xu_xiang_yang · 2015年01月15日 · 最后由 serco 回复于 2015年01月26日 · 3325 次阅读

如题。ruby 中有没有类似于 C++ 中的自增自减操作呢?有的话是原子操作吗?

另外,为什么 1 ++ 1会等于 2 呢? +++有什么区别呢?求大神

+=不需要 rails 吧。刚才试着自定义++报错。 class Numeric def ++ self+self end end

但 1++1 确实能运行。

#1 楼 @xu_xiang_yang 1 ++ 1 对应的完整写法应该是1.+(+ 1),其中,第一个加号就是二元的操作符+,第二个加号是对一个数取正,一元操作符,不是正负符号本身。 1 + 1对应的完整写法是1.+(1)

@loong0 Thx。。。。+=还是 ruby 原生的。那+= 是不是原子操作哩

@africwildman 恩。是我写错了。。。可是 += 是不是原子操作呢??

#5 楼 @xu_xiang_yang 不知道啊,这个估计你得看源码。

#4 楼 @xu_xiang_yang 应该不是的吧。

在 mirb 里的试验,看 opcode:

生成了多行 opcode 的;但是不确定和 CRuby 是否一致的。

@loong0 弱弱的问一句,mirb 是什么

#3 楼 @loong0 三个加号呢?1 ++++ 2 完整写法是怎样?

类似三楼的回复,后一个 + 是对其后的值取正,相反 - 是取负,那么: ++2 => 2 +-2 => -2 +--2 => 2 ++--+-2 => -2 .....

#7 楼 @loong0 应该差不多的

+= 应该会分成两步

  1. 检查是否需要声明变量
  2. 运行 + 操作符
2.1.4 :001 > a + 1
NameError: undefined local variable or method `a' for main:Object
2.1.4 :002 > a += 1
NoMethodError: undefined method `+' for nil:NilClass
2.1.4 :003 > a
 => nil

@serco 不是这样的,+= 1 如果不是原子操作,它会是下面的两步 `1. 从内存取出变量

  1. 对变量进行加 1 操作
  2. 把结果存回内存`

会产生 3 条指令。 如果是原子操作仅会有一步

执行自增的命令(貌似以前学过,这是一个加法器提供的机器指令,专门做自增一。只会产生一条指令)

但我想了想,因为 += 还支持非 1,也就是 a += 2 也是可以的,而机器指令中是没有自增二的操作的,所以推断+=很有可能是非原子操作。

所以我给他加了个锁

#13 楼 @xu_xiang_yang 感觉你没看清楚我的内容。。。 如果你用的是 CRuby,那么不需要纠结是否原子操作,只需要考虑何时 GVL 会释放,GVL 保证不了的当然要加锁。

a+=1其实做的事情很多,不只是你想得那么简单

  1. 如果 a 不存在,声明局部变量 a,初始值为 nil,如果存在,则取出来
  2. +=1里并非自增,Ruby 里的 + operator 实际上也是个 method call,所以支持 +=2
  3. 保存结果回 a
需要 登录 后方可回复, 如果你还没有账号请 注册新账号