Ruby的`Ractor.select` method `move` boolean flag是做什么的?

7vux5j2d  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(78)

我试图理解Ruby的Ractor.select方法中move标志的行为。方法签名:https://ruby-doc.org/3.2.1/Ractor.html#method-c-current
在文档中对函数的移动标志的描述以如下方式描述了该标志:

move boolean flag defines whether yielded value should be copied (default) or moved.

这句话在所有权模型像rust一样的语言中是有意义的。但我想知道这对露比意味着什么
我运行了一段代码来实验这个标志的效果。

should_move = true

puts "MOVE: #{should_move}"
r1 = Ractor.new do
  data = [{name: "tom"}, {name: "dick"}, {name: "harry"}]
  puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}"
  Ractor.yield(data)
  sleep 2
  puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}"
end

ractor, value = Ractor.select(r1, move: should_move)

puts "[OUTSIDE RACTOR] value is: #{value} and value[0] object_id is: #{value[0].object_id}"
p ractor

sleep 3

在上面的代码中,should_move = true和& should_move = false的输出是相同的。

MOVE: true
main.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
[INSIDE RACTOR (before move)] data value is [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and data object id is :60
[OUTSIDE RACTOR (after move)] value is: [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and value[0] object_id is: 80
#<Ractor:#2 main.rb:4 blocking>
[INSIDE RACTOR (after move)] data value is [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and data object id is :60

然后我尝试运行同样的东西,但这一次,我将ractor中的data变量设置为整数值,如下所示:

should_move = true

puts "MOVE: #{should_move}"
r1 = Ractor.new do
  data = 12
  puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data.object_id}"
  Ractor.yield(data)
  sleep 2
  puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data.object_id}"
end

ractor, value = Ractor.select(r1, move: should_move)

puts "[OUTSIDE RACTOR] value is: #{value} and value object_id is: #{value.object_id}"
p ractor

sleep 3

这一次,这种情况下的输出如下:

MOVE: false
main.rb:4: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
[INSIDE RACTOR (before move)] data value is 12 and data object id is :25
[OUTSIDE RACTOR (after move)] value is: 12 and value[0] object_id is: 25
#<Ractor:#2 main.rb:4 blocking>
[INSIDE RACTOR (after move)] data value is 12 and data object id is :25

在这种情况下,移动标志状态也不影响输出。

omqzjyyz

omqzjyyz1#

我认为您忽略了move在Ractor::select上下文中的作用和影响
move将使发送者无法访问发送对象,你可以通过稍微修改你的例子来看到这一点。

r1 = Ractor.new do
  data = [{name: "tom"}, {name: "dick"}, {name: "harry"}]
  puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}"
  Ractor.yield(data, move: true)
  begin 
    puts "[INSIDE RACTOR] data value is #{data} and data object id is :#{data[0].object_id}"
  rescue Ractor::MovedError => e 
    puts
    puts "data is no longer accessible because it was moved"
  end 
end

Ractor.select(r1)

输出量:

[INSIDE RACTOR] data value is [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and data object id is :740

data is no longer accessible because it was moved

这是因为消息data通过yieldmove:true发送。
Ractor::select中,move对应于yield_value

data = [{name: "tom"}, {name: "dick"}, {name: "harry"}]
r1 = Ractor.new(Ractor.current) do |main|
  puts "Received from main: #{main.take}"
end

puts "Ractor.select with yield_value: #{data} and move: true"

Ractor.select(r1, yield_value: data, move: true)

begin 
  puts "Can access data: #{data}"
rescue Ractor::MovedError => e 
  puts
  puts "data is no longer accessible because it was moved"
end

输出量:

Ractor.select with yield_value: [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}] and move: true
Received from main: [{:name=>"tom"}, {:name=>"dick"}, {:name=>"harry"}]

data is no longer accessible because it was moved

这是因为yield_value被移动,因此发送者不再可以访问。

相关问题