Ich habe versucht, den folgenden Code mit Ractor zum Laufen zu bringen.
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.send(1, 2)
r.take
# => 1
# => 2
# => Integer
# => Integer
Es ist ein Mechanismus zur Bereitstellung paralleler / paralleler Funktionen, die in Ruby3 eingeführt wurden. Ursprünglich Guild genannt, wird es seit mehreren Jahren diskutiert.
Weitere Details finden Sie im Video unten.
[JA] Ractor report / Koichi Sasada @ko1
Sie können ein Objekt mit der Methode "send" an Ractor übergeben.
r = Ractor.new do
v = Ractor.recv
puts v
puts v.class
end
r.send(1)
r.take
# => 1
# => Integer
Sie können jedoch nicht mehrere Objekte übergeben, wie unten gezeigt.
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.send(1, 2)
r.take
# =>wrong number of arguments (given 2, expected 1) (ArgumentError)
Es scheint jedoch in Ordnung zu sein, es als Array zu übergeben.
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.send([1, 2])
r.take
# => 1
# => 2
# => Integer
# => Integer
In der Implementierung sieht es so aus (in ractor.rb
im CRuby-Quellcode)
Die aktuelle "send" -Methode verwendet nur ein Objekt als Argument. Sie können auch angeben, ob mit dem Schlüsselwortargument "move" verschoben werden soll.
def send obj, move: false
__builtin_cexpr! %q{
ractor_send(ec, RACTOR_PTR(self), obj, move)
}
end
Die C-Funktion wird mit __builtin_cexpr!
Aufgerufen, und das von der Methode empfangene Argument wird unverändert an die C-Funktion übergeben. Abgesehen davon können Sie mit CRuby kürzlich Code schreiben, der Ruby-Variablen als interne Implementierung an C-Funktionen übergibt.
Ich habe die Send-Methode von Ractor wie folgt umgeschrieben.
def send obj, *arg, move: false
obj = arg.unshift obj unless arg.empty?
__builtin_cexpr! %q{
ractor_send(ec, RACTOR_PTR(self), obj, move)
}
end
Erstens nimmt die "send" -Methode immer ein Objekt als Argument. Die Argumente werden als "obj, * arg, move: false" umgeschrieben, um dieses Verhalten beizubehalten. Wenn mehrere Objekte wie "send (1, 2)" übergeben werden, wird das Argument als Array an "* arg" übergeben.
Wenn arg
kein leeres Array ist, werden mehrere Objekte übergeben, und das obj
, das schließlich an die C-Funktion übergeben wird, wird in eine Zusammenführung des ersten Arguments und des Arguments variabler Länge konvertiert. Ich werde.
Sie müssen lediglich den geänderten CRuby-Quellcode erstellen.
Sie können jetzt mehrere Objekte wie folgt an Ractor übergeben:
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.send(1, 2)
r.take
# => 1
# => 2
# => Integer
# => Integer
ref: Guild → Ractor ref: https://github.com/ko1/ruby/blob/ractor/ractor.ja.md ref: [[JA Ractor report / Koichi Sasada @ko1
Übrigens, wenn Sie einen Affen-Patch möchten, können Sie eine Methode erstellen, die wie folgt verpackt ist.
class Ractor
def multi_send(obj, *args, move: true)
obj = args.unshift obj unless args.empty?
send(obj, move: move)
end
end
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.multi_send(1, 2)
r.take
Da die Auswahl an Affenpflastern groß ist, ist es möglicherweise besser, "Verfeinerungen" zu verwenden, da dies weniger Auswirkungen hat, wenn Sie es in der Praxis verwenden.
module RefineRactor
refine Ractor do
def multi_send(obj, *args, move: true)
obj = args.unshift obj unless args.empty?
send(obj, move: move)
end
end
end
using RefineRactor
r = Ractor.new do
v1, v2 = Ractor.recv
puts v1
puts v2
puts v1.class
puts v2.class
end
r.multi_send(1, 2)
r.take
Recommended Posts