Ruby ã®éçºããã¦ããæè¡é¨ã®ç¬¹ç°ã§ããå¨ãèªè»¢è»ã«ä¹ãå§ããã¾ã ä¸å®ãªãããã£ã¨ã¤ãã¦ããªããã°ãªãããå°ã追ã£ããã¾ãããã ãã§æ¯åããã¤ããæãã«ãªã£ã¦ãã¾ããéåããªãã¨ã
ããæ°å¹´ãRuby ã§ä¸¦åå¦çãæ°è»½ã«æ¸ãããã®ä»çµã¿ã§ãã Ractor ã Ruby 3.0 ã§å°å ¥ããã¨ããä»äºããã¯ãã¯ãããã§ã®ä¸»åã¨ãã¦è¡ã£ã¦ãã¾ããï¼ã¯ãã¯ãããããããããã¨è¨ããã¦ããããã§ã¯ãªããRuby ãåé²ãããã¨ããããã·ã§ã³ã®ä¸ã§è¡ã£ã¦ãã¾ããï¼ã
Ractor ã¯ããã¨ã㨠Guild ã¨ããååã§éçºãã¯ããã2020å¹´ã®æ¥é ãRactor ã¨ããååã«å¤æ´ãããã¨ã«ãã¾ãããããã¤ãã®æ©ä¼ã§çºè¡¨ãã¦ãã¾ããä¸è¨ã¯ãRubyKaigi ã§ã®çºè¡¨ã®è¨é²ã§ãã
- A proposal of new concurrency model for Ruby 3 - RubyKaigi 2016
- Guild Prototype - RubyKaigi 2018
- Ractor report - RubyKaigi Takeout 2020
ããã¦ãæ¨æ¥ãªãªã¼ã¹ããã Ruby 3.0 ã§å°å ¥ããã¾ããããã£ãï¼ããã ãã¾ã ä»æ§ãå¤ãããããªãã¨ã¨ãè²ã å®è£ ãããªãã¦ããªãã®ã§ãå®é¨çæ©è½ã¨ãã¦å°å ¥ããã¦ããã使ãã¨è¦åãåºãç¶æ ã§ãã
æ¬ç¨¿ã§ã¯ãRactorã®ç°¡åãªãç´¹ä»ã¨ãRactor ã®ï¼ç§ã®èããï¼ä½ç½®ã¥ããããã¦å°æ¥ã® Ruby ï¼ä¸»èªã大ããï¼ã«ã¤ãã¦ãç´¹ä»ãã¾ãããã¾ã how to ãªå 容ã§ã¯ããã¾ããã
Ractor èªä½ã®è©³ç´°ã¯ãruby/ractor.md at master · ruby/ruby ã«ããã®ã§ãåèã«ãªãã£ã¦ãã ãããã¾ããå æ¥ã®æ¬ããã°è¨äº Ruby ã« Software Transactional Memory (STM) ãå ¥ãããã¨æã£ã話 - ã¯ãã¯ãããéçºè ããã° ã«ããããã¤ãåºæ¬çãªä½¿ãæ¹ãè¼ã£ã¦ãã¾ãã
ç°¡å㪠Ractor ã®ç´¹ä»
ä¾ãç¨ãã¦ãRactor ã®æ©è½ã¨ç¾ç¶ã«ã¤ãã¦ç°¡åã«ãç´¹ä»ãã¾ãã
Ractor ã§ã®ä¸¦åå¦çã§ãå®éã«éããªãä¾
Ruby 3.0 ã®ãªãªã¼ã¹æï¼Ruby 3.0.0 ãªãªã¼ã¹ï¼ã«ãããRactor ããã°ã©ã ã®ä¾ãè¦ã¦ã¿ã¾ãããããããç§ãæ¸ãã¾ãããå¼ç¨ãã¾ãã
def tarai(x, y, z) = x <= y ? y : tarai(tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y)) require 'benchmark' Benchmark.bm do |x| # sequential version x.report('seq'){ 4.times{ tarai(14, 7, 0) } } # parallel version x.report('par'){ 4.times.map do Ractor.new { tarai(14, 7, 0) } end.each(&:take) } end
ï¼1è¡ def ã¨å¼ã°ããæ°æ©è½ã使ã£ã¦ããã®ããªã·ã£ã¬ãã¤ã³ãã§ããå®ç¾©èªä½ã¯4è¡ã ãã©ï¼
ãã®ããã°ã©ã ã§ã¯ããã³ããã¼ã¯ã§ããç¨ãããã竹å
é¢æ°ï¼ç«¹å
é¢æ° - Wikipedia ï¼tarai(14, 7, 0)
ãã4åå®è¡ãããï¼seq
ï¼ãRactor ãç¨ãã¦4並åå®è¡ãããï¼par
ï¼ã§ãå®è¡æéã測ã£ã¦ãã¾ãã
Ractor.new { tarai(14, 7, 0) }
ããæ°ãã Ractor 㧠tarai()
é¢æ°ãå®è¡ããé¨åã§ããThread.new{}
ã®ããã«ããããã¯ã®é¨åãæ°ãã Ractorï¼ã®ä¸ã§ä½ã£ã Threadï¼ã§å®è¡ãã¾ããRactor ãã¾ããã ã¹ã¬ããã¯ä¸¦åã«å®è¡ãããã®ã§ããã® tarai()
ã並åã«å®è¡ãããã¨ããããã§ãã
Ractor#take
ã«ãã£ã¦ããã® Ractor ãå¤ãè¿ãã®ãå¾
ã¤ãã¨ãã§ãã¾ãã
ããã«ãçµæããªãªã¼ã¹æããå¼ç¨ãã¾ãã
Benchmark result: user system total real seq 64.560736 0.001101 64.561837 ( 64.562194) par 66.422010 0.015999 66.438009 ( 16.685797)
çµæ㯠Ubuntu 20.04, Intel(R) Core(TM) i7-6700 (4 cores, 8 hardware threads) ã§å®è¡ãããã®ã«ãªãã¾ããé次å®è¡ããã¨ããããã並ååã«ãã£ã¦3.87åã®é«éåãã¦ãããã¨ããããã¾ãã
ãã®ãã·ã³ã笹ç°ã®èªå® ã«ãããã·ã³ãªãã§ãããã¡ããã¨4並åã§4åè¿ãæ§è½ãåºã¦ãã¦ããã£ãããã¨ããçµæã«ãªã£ã¦ãã¾ãããããªæãã§ãRactor ãç¨ãããã¨ã§ã並åè¨ç®æ©ä¸ã§ä¸¦åå¦çãè¡ããã¨ãã§ãããã¾ãããã°ä¸¦åå®è¡ã«ããé度åä¸ãçãã¾ãã
ç¾ç¶ã® Ractor
å ã»ã©ã®ä¾ã§ã¯ã4åè¿ãé«éåãéæãããã¨ãã§ãã¾ããããã ããããã¹ãã±ã¼ã¹ã¨ãããããã£ã³ããªã³ãã¼ã¿ã¨ãããããã¾ãããä¾ã§ãã¦ãå¤ãã®å ´åãRactor èªä½ã¯ãã¾ã ã¾ã ãã¾ããã¨æ§è½ãåºãã¦ãã¾ããã
ä¾ãã°ããªãªã¼ã¹ç´åã«çºè¦ãããæ§è½ä¸ã®å¤§ããªåé¡ããã¢ã®ããã«ããã¾ãæå³ãããã¾ããããtarai
é¢æ°ã®å
é ã§ãObject
ãåç
§ãã¦ã¿ã¾ãããã
def tarai(x, y, z) = Object && x <= y ? y : tarai(tarai(x-1, y, z), tarai(y-1, z, x), tarai(z-1, x, y))
å¿ ãçã«ãªãã®ã§ãä¸è¦ãªåç §ã§ããã§ã¯ãåãããã«ãã³ããã¼ã¯ãã¨ã£ã¦ã¿ã¾ãããã
user system total real seq 79.807530 0.000000 79.807530 ( 79.807818) par 902.635763 432.107713 1334.743476 (343.626728)
ãªãã¨æ¡éãã4åéããªãã¬ã4åé
ããã¨ããæ®å¿µãªçµæã«ãªã£ã¦ãã¾ãã¾ããããªããããªãã¨ã«ãªã£ã¦ãã¾ããã¨ããã¨ãå®æ°ï¼Object
ï¼ã®åç
§ãé
ãããã§ãã
çç±ãå°ã解説ããã¨ã次ã®ããã«ãªãã¾ãã
- (1) å®æ°åç §æã«å©ç¨ããã¤ã³ã©ã¤ã³ãã£ãã·ã¥ãã¹ã¬ããã»ã¼ãã§ãªãã£ããããmain Ractor 以å¤ã§ã¯ãã£ãã·ã¥ãç¡å¹ã«ãã¦ãã
- (2) å®æ°åç §æãå®æ°ãã¼ãã«ã¯ Ractor éã§å ±æãããããããã¯ãè¡ãããããã¯ã競åããã¨ãã£ã¡ãé ã
(1) 㨠(2) ã®ç¸ä¹å¹æã§ã ãã¶é ããªã£ã¦ãã¾ã£ã¦ãã¾ããæ®å¿µç¡å¿µããªãªã¼ã¹ç´åã«çºè¦ããã®ã§ãããããç´ããã¨æã£ã¦ãã¾ãï¼ä¿®æ£èªä½ã¯ããããªã«é£ãããªãï¼ãRactor èªä½ã¯ãããããã®ããã§ã¤ãã§ã¤ãããããã¨ããã¯ãªãªãã£ã¼ã«ãªã£ã¦ãã¾ãã
ããã«éãããããããããããªãã£ã¼ãããã¯ï¼ä¸»ã«è¦æ ï¼ãåããã¨æãã¾ãããããã«å¯¾å¦ãã¦ãããã¨ã§ãå®æ度ãããã¦ãããã¨æã£ã¦ãã¾ããã¨ããããã§ããããããããããããªãã®ï¼ãã¨ããããããé ããã ãã©ãã¨ãã£ããã£ã¼ãããã¯ãæè¿ãã¾ãã伸ã³ãããããªãRactorããä¸ç·ã«è²ã¦ã¦ãã£ã¦ãã ããã
ã¨ããããã§ãã¾ã ããããã¯ãªãªãã£ãªã®ã§ãRactor.new{}
ããã¨è¦åãåºã¾ãã
warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
æ¸ãã¦ããéããä»æ§ã fixed ã¨ããããã§ã¯ãªãã®ã§ãå¤ããããããã¾ããããã¡ãããã£ã¼ãããã¯ããå¾ ã¡ãã¦ããã¾ãã
Ractor ã®åºç¤
Ractor ã®ä»æ§ã¯ãä¸è¨ã®ãã¤ã³ããåºç¤ã¨ãã¦ãã¾ããããã¤ã¾ãã§ãç´¹ä»ãã¾ãã
Ractor.new{}
ã§è¤æ°ã® Ractor ãä½ããã¨ãã§ãããããã¯ä¸¦åã®å®è¡ããã- Ractor éã®ãªãã¸ã§ã¯ãã®å
±æã¯ã ãããç¦æ¢ããã¦ãã
- å ±æä¸å¯ (unshareable) ãªãã¸ã§ã¯ã
- ç¹æ®ãªå
±æå¯è½ (shareable) ãªãã¸ã§ã¯ãã ãå
±æå¯è½
- Immutable ãªãã¸ã§ã¯ã
- Class/Module ãªãã¸ã§ã¯ã
- ãã®ä»
- 2種é¡ã®ã¡ãã»ã¼ã¸äº¤ææ¹å¼
- pushå:
r.send(obj)
->Ractor.receive
- pullå:
Ractor.yield(obj)
->r.take
- pushå:
r = Ractor.new do Ractor.receive # :ok ãå診ããããããããã¯ã®è¿å¤ã¨ãã end r.send(:ok) # r 㸠:ok ãéãï¼pushï¼ p r.take #=> r ã®ãããã¯ã®è¿å¤ :ok ãåå¾ããï¼pullï¼
Ractor.select
ã«ããåæå¾ ã¡
r1 = Ractor.new{ :r1 } r2 = Ractor.new{ :r2 } r, msg = Ractor.select(r1, r2) # ã©ã£ã¡ãæ©ãçµãã£ãã»ãã®ã¡ãã»ã¼ã¸ãå¾ããã
- ã¡ãã»ã¼ã¸ã®éä¿¡æ¹æ³
- è¤è£½: ãã£ã¼ãã³ãã¼ãã¦éä¿¡
r.send(obj)
- 移å: æµ
ãã³ãã¼ãè¡ãããéä¿¡å
ã§ã¯ãã®ãªãã¸ã§ã¯ããå©ç¨ä¸å¯ï¼ä½¿ãã¨ãã©ããªã¡ã½ããã
method_missing
ã«ãªãï¼ruby r.send(obj, move: true) obj.inspect #=> `method_missing': can not send any methods # to a moved object (Ractor::MovedError)
- æ å ±ã®ä¸çã§ã¯ãèªåçã«ã³ãã¼ã«ãªããã¨ãå¤ãã®ã§ãã移åãã¨ããæ¦å¿µã¯é¢ç½ãã¨æãï¼ããããGuild ã¨ããè¨èã®ç±æ¥ã ã£ãï¼
- è¤è£½: ãã£ã¼ãã³ãã¼ãã¦éä¿¡
- è¤æ° Ractor ãåããå ´åãããã¤ãã®æ©è½ã«å¶éï¼å¾è¿°ï¼
詳細ã¯ããã¥ã¡ã³ãï¼ruby/ractor.md at master · ruby/rubyï¼ããããã¯Ruby ã« Software Transactional Memory (STM) ãå ¥ãããã¨æã£ã話 - ã¯ãã¯ãããéçºè ããã° ã®åé ã®ä¾ãªã©ãã覧ãã ããã
以éã¯ãæè¿å ¥ã£ã¦ãã¾ã ãã¾ãç´¹ä»ããã¦ããªãæ©è½ã«ã¤ãã¦ãç´¹ä»ãã¾ãã
Ractor#receive_if
ã«ããé¸æçåä¿¡
Ractor.receive
㯠Ractor ã«éãããã¡ãã»ã¼ã¸ããFIFO ã§åãåºãã¨ããæ©è½ã§ããããã ããããã ã¨ãè¤æ°ã® Ractor ããé ä¸åã§éããã¦ããã¡ãã»ã¼ã¸ããåºå¥ãã¦æ±ããã¨ãã§ãã¾ããã
Erlang/Elixir ãªã©ã®è¨èªã§ã¯ãããã§ãã¿ã¼ã³ããããç¨ãã¾ãã
ï¼Processes - The Elixir programming languageããå¼ç¨ï¼
# elixir ã®ä¾ iex> receive do ...> {:hello, msg} -> msg ...> {:world, _msg} -> "won't match" ...> end "world"
ãã®ä¾ã§ã¯ãreceive
ã§ãpat -> expr
ã®ããã«ãpat
ã«ãããããã¡ãã»ã¼ã¸ãè¦ã¤ããã°ãexpr
ãå®è¡ãããã®ããã«è¨è¿°ãããã¨ãã§ãã¾ãã
Ractor.receive
ã§ä¼¼ããããªãã¨ãããã¨ããããããªãã£ãã¨ããincoming queueã«ã¡ãã»ã¼ã¸ãæ»ããã¨ãã§ããªããããä¼¼ããããªæ©è½ãä½ããã¨ãã§ãã¾ããï¼receive
æ¸ã¿ã®ã¡ãã»ã¼ã¸ãããã¦ããä»çµã¿ã¨ãããããåãåºãä»çµã¿ãä½ã£ã¦ãreceive
ã¯ç´æ¥ç¨ããªããã¨ããã°ã§ãããã¨ããªãã§ãï¼ã
ããã§ãRactor.receive_if
ãï¼çµæ§ãªãªã¼ã¹ç´åã«ï¼å°å
¥ããã¾ããã
Ractor.receive_if{|msg| /foo/ =~ msg}
ãã®ä¾ã§ã¯ãåä¿¡ããã¡ãã»ã¼ã¸ã®ãã¡ã/foo/
ã«ãããããå ´åããããã¯ã true ãè¿ãããã®ã¨ãã¯ãã㦠incoming queue ããã¡ãã»ã¼ã¸ãåé¤ãã¾ãã
ãã®æ©è½ãç¨ãããã¨ã§ããããã¿ã¼ã³ã«åè´ããã¡ãã»ã¼ã¸ã®ã¿åä¿¡ãããã¨ãã§ãã¾ãã
ãã ãErlang/Elixir ã«ãã£ããããªããã¿ã¼ã³A ãªãå¦çAããã¿ã¼ã³Bãªãå¦çBãã¨ãããããªãã¨ã¯æ¸ãã¾ãããã¨ããã®ãããã®ãããã¯ã¯è¿°èªã¨ã㦠true/false ãè¿ãã¹ããã®ã§ããããã§ãã
ç¡ãããæ¸ãã¨ããã¨ããããªæã㧠Proc (labmda) ãè¿ããããããããã¯ã®å¤å´ã§å®è¡ãããã¨ãã¦è¨è¿°ãããã¨ãå¯è½ã§ãï¼break ãªã©ã§ãããã¯ãæããã¨ãtrue ãè¿ããã¨ãã®ããã« incoming queue ããã¡ãã»ã¼ã¸ãæãã¾ãï¼ãããã¦ããã®å¾ã«å®è¡ãããå¦çã Proc ã§è¿ãã¦ããã®ã§ããããå¼ã¹ã°å¯¾å¿ããå¦çï¼taskA ã taskBï¼ãå®è¡ã§ãããã¨ãããã®ã§ãã
Ractor.receive_if do |msg| case msg when patA break -> { taskA(msg) } when patB break -> { taskB(msg) } end end.call
ãããããæ£ç´æ¸ããããªãã®ã§ãRuby 3.1 以éã«ãã¯ããå ¥ãã°ããªããããæãã«ã§ãããã ãªããã¨èãã¦ãã¾ãã
è¤æ° Ractor ãåããå ´åãããã¤ãã®æ©è½ã«å¶é
ããã¾ã§ãRactor ããªããã°åé¡ãªã使ãã¦ããæ©è½ããRactor éã§ã®ãªãã¸ã§ã¯ãã®å ±æãæé¤ãããããè¤æ° Ractor ç°å¢ã«ããã¦å¶éããã¾ãããRactor ã使ããªããã°ï¼main Ractor ã ãã§å©ç¨ãããªãï¼ãããã¾ã§éãå¶éã¯ããã¾ããã
å ·ä½çã«ã¯ã次ã®æä½ã main Ractor ã ãã§å©ç¨å¯è½ã«ãªãã¾ãã
- (1) ã°ãã¼ãã«å¤æ°ãã¯ã©ã¹å¤æ°ã®è¨å®ã»åç §
- (2) å®æ°ã«å ±æä¸å¯ãªãã¸ã§ã¯ãã®è¨å®ã»åç §
- (3) å ±æå¯è½ãªãã¸ã§ã¯ãã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã®è¨å®ã»åç §ï¼ã¨ãã«ãã¯ã©ã¹ã»ã¢ã¸ã¥ã¼ã«ã§åé¡ã«ãªãï¼
ã©ã®æ©è½ãã使ããã¦ããã¨ä¸çºã§ main Ractor 以å¤ã§å©ç¨ã§ããªããªãã¾ãããã®ä¸ã§ãä¸çªã¯ã¾ããããªã®ã¯ã(2) 㨠(3) ã§ããããã
C = ["foo", "bar"] # NG: (2) å®æ°ã«å ±æä¸å¯ãªãã¸ã§ã¯ããè¨å® class C @bar = 42 # NG: (3) å ±æå¯è½ãªãã¸ã§ã¯ãã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ãè¨å® def self.bar @bar # NG: (3) å ±æå¯è½ãªãã¸ã§ã¯ãã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ãåç § end def self.bar=(obj) @bar = obj # NG: (3) å ±æå¯è½ãªãã¸ã§ã¯ãã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ãè¨å® end end
ãã使ããã¦ããããªããã°ã©ã ã§ãããã®å¶éã«ãããå¤ãã®ã©ã¤ãã©ãªããè¤æ° Ractor ä¸ã§å©ç¨ãããã¨ããç¾å¨ã§ãã¾ãããä»å¾ããã¾ããã¨æ¸ãæããé²ãã¨ãRactor ã¯å©ç¨ãããããã®ã«ãªã£ã¦ããã¨æãã¾ãã
ãã¦ãã§ã¯ã©ã®ããã«ããã°ããã§ããããã
(2) ã«ã¤ãã¦ã¯ã# shareable_constant_value: ...
ã¨ãããã©ã°ããæ°è¨ããã¾ããã
# shareable_constant_value: literal C = ["foo", "bar"]
ãã®ãªãã·ã§ã³ã§ none
ï¼ããã©ã«ãã®ã¢ã¼ãï¼ä»¥å¤ãé¸ã¶ã¨ãå®æ°ãå
±æå¯è½ãªãã¸ã§ã¯ããåç
§ãã¦ãããã¨ãããã¨ãä¿è¨¼ã§ãã¾ãããã®ä¾ã§ã¯ãliteral
ãé¸ãã§ãã¾ããããã¯ãå®æ°ã®å³è¾ºå¤ãã¤ã¾ã代å
¥ãããªãã¸ã§ã¯ãããªãã©ã«ã®ããã«è¨è¿°ããããªãã¸ã§ã¯ããªããå帰çã«freeze
ãã¦ãããã¨ã§ãimmutable ãªå
±æå¯è½ãªãã¸ã§ã¯ããçæããå®æ°ã«ä»£å
¥ãã¾ãããªãã©ã«ã§ãªããã°ãå
±æå¯è½ã§ãããå®è¡æã«ãã§ãã¯ãããã¨ã§ãå
±æä¸å¯ãªãã¸ã§ã¯ããå®æ°ã«ä»£å
¥ããããã¨ãé²ãã¾ãã
æå®ã§ãããªãã·ã§ã³ã¯ãnone
㨠literal
以å¤ã«ããã®2ã¤ãæå®ã§ãã¾ãã
- experimental_everything
- å³è¾ºå¤ã®å¤ãå ±æå¯è½ãªãã¸ã§ã¯ãã«å¤æãã
- experimental_copy
- å³è¾ºå¤ã®å¤ãã¾ãã³ãã¼ããã³ãã¼ã«å¯¾ãã¦å ±æå¯è½ãªãã¸ã§ã¯ãã«å¤æå¦çãè¡ã
everything
ã¯å¯ä½ç¨ãæ°ã«ãªãã¾ãããcopy
ã¯å
ã®ãªãã¸ã§ã¯ãã«å½±é¿ãä¸ããªããããå¯ä½ç¨ãã»ã¼èµ·ããã¾ããããã ããã³ãã¼ã«ãã£ã¦è¥å¹²æéããããããããã¾ããã
(3) ã®ãå
±æããã mutable ãªå¤ã«ã¤ãã¦ã¯ãgem ã«ãªãã¾ãããRactor::TVar
ï¼ractor-tvar | RubyGems.orgï¼ãç¨ããã¨è¯ãã¨æã£ã¦ãã¾ãã
class C BAR = Ractor::TVar.new 42 def self.bar Ractor::atomcally{ BAR.value } end def self.bar=obj Ractor::atomcally{ BAR.value = obj } end end
Ractor::atomcally
ãæ¯åæ¸ããªãã¨ãããªãã®ã¯åé·ãªæ°ããã¾ããããã㧠Ractor éã«ã¾ãããå
±æç¶æ
ãæä½ãã¦ãããã¨ããã®ãæ示ã§ãã¦ãé·ãç®ã§è¦ãã¨å©ç¹ã«ãªãã®ã§ã¯ãªããã¨æã£ã¦ãã¾ãã
æ¡å¼µã©ã¤ãã©ãªã® Ractor 対å¿
C ãªã©ã§è¨è¿°ãããæ¡å¼µã©ã¤ãã©ãªã¯ãããã©ã«ãã§ã¯ main-Ractor 以å¤ã§ã¯åãã¾ããï¼æä¾ããã¦ããã¡ã½ãããå¼ã¼ãã¨ããã¨ãRactor::UnsafeError
ã«ãªãã¾ãï¼ã
対å¿ãããããã«ã¯ãè¤æ° Ractor ã§å®è¡ãã¦ãããã¨ã確èªãã¦ãrb_ext_ractor_safe(true)
ã§ããã®æ¡å¼µã©ã¤ãã©ãªã Ractor ã®ãµãã¼ãããã¦ãããã¨ãã¤ã³ã¿ããªã¿ã«æãã¦ããããã¨ãå¿
è¦ã§ãã
対å¿ãããããã®ãã§ãã¯ãã¤ã³ãã«ã¤ãã¦ã詳細ã¯ãruby/extension.rdoc at master · ruby/ruby ã«ã¾ã¨ãã¦ããã¾ãããã ãããã¾ãå¤ãªãã¨ãã¦ãªããã°ãããã¦ã Ractor 対å¿ã¯ç°¡åãããªãããªã¨æã£ã¦ãã¾ãã
Ractor ã®èæ¯
ããããã¯ãå ·ä½çãªã³ã¼ãã®è©±ã§ã¯ãªããRactor ã«é¢ããæ¤è¨ã«ã¤ãã¦ããã®ä¸ç«¯ããç´¹ä»ãã¾ãã
è¤æ°ã³ã¢ã®CPUãæ®éã«ãªã£ã¦ããæ¨ä»ã並åè¨ç®ãè¨è¿°ãããã¨ãããã¼ãºã¯ã©ãã©ãé«ã¾ã£ã¦ãã¾ããã¨ãããã¬ã¼ãºã¯ãç§ã大å¦ã§ç 究ãã¦ãã10年以ä¸åããå®çªã®åæ¯ãã§ãããå®éãé«æ§è½ãªã½ããã¦ã§ã¢ãæ¸ãã®ã«ã並åè¨ç®ã¯å¿ é ã§ãããã¨ã«ã©ãªããç°è«ã¯ãªãã§ãããã
並åè¨ç®ãè¡ãããã«ã¯ãããã°ã©ã ã並åè¨ç®ã«å¯¾å¿ãã¦ããªããã°ãªãã¾ããããã®ããã«ã¯ã並åããã°ã©ãã³ã°ãå¿ è¦ã«ãªãã¾ãããã§ã«ãå¤ãã®ããã°ã©ãã³ã°è¨èªã並åè¨ç®ã®ããã®ä»çµã¿ãåãã¦ãã¾ãã
ã¹ã¬ããããã°ã©ãã³ã°ã¯é£ãã
ãã ã並åè¨ç®ãè¡ãããã°ã©ã ã¯ãã ãã¶é¢åããããã¨ãç¥ããã¦ãã¾ããã¨ãã«ãã¹ã¬ããããã°ã©ãã³ã°ã¯ããããããªçç±ãããæ£ããããã°ã©ã ãæ¸ããã¨ãå°é£ã§ããRuby ã§ããã¹ã¬ãã㯠Thread.new{ ... }
ã¨æ¸ããã¨ã§ãç°¡åã«ä½ããã¨ãã§ãã¾ãã
ãã¨ãã°ãåãã¡ã¢ãªé åã«ãè¤æ°ã®ã¹ã¬ãããåæã«èªã¿æ¸ãããã¨ãããããªãã¨ã«ãªãã¾ããããã®é çªã§èªã¿æ¸ããã¦ãããã大ä¸å¤«ãã¨ãããèãã¦ããã°ã©ã ãããã¦ããã³ã³ãã¤ã©ã®æé©åã«ãã£ã¦èªã¿æ¸ãã®é åºãå¤ãã£ãããã¦ãé次å¦çãã¦ããã¨ãã«ã¯æ°ã¥ããªãã£ãåé¡ãçãããã¨ãå¤ãã§ãããã®åé¡ããããã¹ã¬ããå®å ¨ã®åé¡ã¨ããã¾ãã
ãããã°æã«ã¯ãé決å®çï¼non-deterministicï¼ãªæåãåé¡ã«ãªãã¾ããé次å¦çã¯ã2度å®è¡ããã°ãã ãããåãçµæã«ãªãã¾ãï¼ããããçã®è¯ããã°ãå¤ãã§ãï¼ãããããè¤æ°ã®ã¹ã¬ãããã©ã®ããã«åããã¯ãã¹ã¬ããããã¼ã¸ã£ã®ä»äºã«ãªããä¸è¬çã«ã¯å¶å¾¡ãããã¨ã¯é£ããã2度ç®ã®å®è¡ã§ã¯ç°ãªãçµæã«ãªããã¨ãå¤ãã§ãããã®ãããåé¡ãçºè¦ãã¦ãããã®åé¡ãåç¾ãããã¨ãé£ãããã¤ã¾ããããã°ããããããã©ãããã§ãã
ãã®é決å®æ§ã¯ãã»ãã¨ãã«ã¿ã¤ãã³ã°ããä½ãããªãã¨èµ·ããªããã°ãªããã ã¨ããã£ãã«åç¾ããªãã®ã§ãããã°ã£ã¦ä¿®æ£ããã¦ããæ¬å½ã«ãã®åé¡ã解決ããã®ãããããªããã¨ãã£ã話ãããã¾ãã
ã¡ã¢ãªãå ±æããåæã®èªã¿æ¸ãã¯é£ãã
ã¹ã¬ããããã°ã©ãã³ã°ã®1ã¤ã®åé¡ç¹ã¯ãè¤æ°ã¹ã¬ããã§ã¡ã¢ãªãåæã«èªã¿æ¸ããå¯è½ã§ãããã¨ããç¹ãæãããã¾ããåæã«èªã¿æ¸ããèµ·ããå¯è½æ§ãããã¡ã¢ãªé åã«ããã¦ã¯ãããã¯ãããã¦æä»å¶å¾¡ãããªã©ãä»ã®ã¹ã¬ããã¨åæããªããå¦çãé²ããå¿ è¦ãããã¾ãã
ããå¾ã ã«ãã¦ããããããã¡ããã¨ã¢ã¯ã»ã¹ããåã«ã¯ããã¯ãã¨ããã¿ãããªãã®ã¯ãå¿ããã¡ã§ãã人éã¯ãã¦ãã«ãªããããã®ã§ããç§ã¯ããã£ã¡ã ãå¿ãã¦çãç®ã«ãã£ã¦ãã¾ãã
ãç§ã¯å¤§ä¸å¤«ãã¡ããã¨åæã¨ãä»è¾¼ãããã¨ãã人ãããã£ãããã£ã¡ããå¯è½æ§ã¯ãããã§ãããã¾ããããã¤ãããã£ããããããªä¾ã並ã¹ã¦ã¿ã¾ãã
- ããã°ã©ã ã®è¦æ¨¡ã大ãããªããæ³å®ã¨å¥ã®ç¨éã§ãã¼ã¿ãç¨ãã¦ããã£ããããã¯ãå¿ è¦ã§ãããã¨ãå¿ãã
- ãã¼ã¿æ§é ãè¤éåããå ±æããã¦ãããã¨ã«æ°ã¥ããããã£ããããã¯ãå¿ãã
- å¥ã®äººï¼å°æ¥ã®èªåããï¼ããã£ããããã¯ãå¿ãã¦ã¢ã¯ã»ã¹ãã
ä»ã«ãããããããã¨æãã¾ãã
ã¡ãªã¿ã«ããã¡ããã¨åãããã°ã©ã ãæ¸ããã¨ããã®ãé£ããã§ãããããã«ãéãããã°ã©ã ãæ¸ããã¨ããã®ãé£ããåé¡ã§ããä¾ãã°ãç°ãªãã¡ã¢ãªã«ã¯ãç°ãªãããã¯ãæ¬å½ã«å¿ è¦ãªæã«ã ãç¨ããã»ããï¼ã¤ã¾ããç´°ç²åº¦ããã¯ãç¨ããã»ããï¼ä¸¦å度ã¯ãããã並åå¦çã®æ§è½åä¸ãã¾ãããããã¯ã®å¦çï¼ç²å¾ã¨éæ¾ï¼ãé »ç¹ã«è¡ãå¿ è¦ãåºã¦ãã¦ãä¸æã«ä½ãã¨é ããªã£ã¦ãã¾ãã¾ãã
é£ããã«å¯¾ãã対å¿ç
ãã¡ãã人é¡ã¯è³¢ãã®ã§ãæ§ã ãªå¯¾çãèãã¦ãã¾ããã
- ããã¯ãªã©ããã¡ãã¨ä½¿ã£ã¦ãããããã§ãã¯ãããã¼ã«ã®å©ç¨ï¼valgrin/helgrindãthread-sanitizerã...ï¼
- ããã¯ãªã©ãèªç¶ã«ä½¿ããã¨ãã§ãããã¼ã¿æ§é ã®å°å ¥ï¼åæãã¥ã¼ãTransactional memoryã...ï¼
- åã«ãããã¼ã¿ã®ææç³»ã®æ示ï¼Rustãªã©ï¼
- æ¸ãè¾¼ã¿ãç¦æ¢ãã¦ãåæã«èªã¿æ¸ããèµ·ãããªãï¼Erlang/Elixir, Concurent-haskell ãªã©ï¼
- ããããããã»ã¹ãªã©ã§åé¢ãã¦ãå ±æããªãï¼shell, makeï¼
ããã©ããå®å ¨ã«è§£æ±ºããã®ãé£ããããRuby ã«å°å ¥ããã®ã¯å°é£ã§ãï¼å人ã®è¦è§£ã§ããå¥ã®è¦æ¹ãããã¨æãã¾ãï¼ã
- ãã¼ã«ã¯æ¼ããçãã¾ããã¾ããMRI ã®æ§æä¸ãï¼ç¾å®çãªã³ã¹ãã§ï¼å®ç¾ããªããªãå°é£ã§ã
- ãã¼ã¿æ§é ãæ£ããæ±ãã°åé¡ãªãã¦ããããã¯ãå¿ããã®ã¨åæ§ã«ãã£ããæ£ãããªã使ãæ¹ããã¦ãã¾ãã¾ã
- Ruby ã«ã¯ãã®æã®åãè¨è¿°ããæ¹æ³ããªãããå°é£ã§ãï¼ææ³ãå ¥ããã®ã¯ãã£ã¨é£ããï¼
- æ¸ãè¾¼ã¿ç¦æ¢ï¼ä¾ãã°ãã¤ã³ã¹ã¿ã³ã¹å¤æ°ã¸ã®ä»£å ¥ç¦æ¢ï¼ã¯ãäºææ§ã大ãã«å£ãã¾ã
æå¾ã®ãããããããã»ã¹ãªã©ã§åãã¦ãååç¶æ ãå ±æããªããã¨ãããshell ãªã©ã§å©ç¨ããã¦ããã¢ããã¼ãã¯ãRuby ã§ããã«ãããã»ã¹ããã°ã©ãã³ã°ã¨ãã¦ãã§ã«è¡ããã¦ãã¾ããdRubyãUnicornãparalle.gem ã®ããã»ã¹ã¢ã¼ããªã©ãããã§ãããéä¿¡ããå ´åã«ã²ã¨æéããããã¨ããã¢ããã¼ãã«ãªã£ã¦ãã¾ãã
ãã®ã¢ãã«ã§ã¯ãããããã®ã³ã³ãã¼ãã³ããåç´ã«ä½ããã¨ãã§ããã¾ãã« UNIX æµã®éçºã®å©ç¹ãå¹ãã¦ãã¾ãããã¤ããªã©ã§ãã¾ãã¤ãªãããã¨ã§ããããããç¬ç«ã«ä¸¦åå®è¡ããããã¨ãã§ããããmake ã§ä¾åé¢ä¿ã®ã«ã¼ã«ãè¨è¿°ãããã¨ã§ãããããã®ã¿ã¹ã¯ãè¯ãæãã«ä¸¦åå®è¡ããããã¨ãã§ãã¾ããã¾ããå¥ã®è¨ç®æ©ã«å¦çãåæ£ããããã¨ããæ¯è¼ç容æã§ãã
ãã ãããã»ã¹ãè¤æ°ããæãã«ä¸¦ã¹ãã ãã ã¨ããã¤ãã ãã ã¨ã¡ãã£ã¨è¡¨ç¾åãå¼±ãï¼ãã¤ãã©ã¤ã³ä¸¦åå¦çã«ç¹åãã¦ããï¼ãmake ãããã¾ãè¤éãªãã¨ã¯æ¸ãã¾ãããå è¿°ãã Unicorn ãªã©ãããããã¿ã¼ã³ã«ç¹åãã¦ãã¾ããã
ãããããã³ãã¥ãã±ã¼ã·ã§ã³ã主ã«ãã¤ãã§è¡ããããéä¿¡ã®ããã®æéããè¤éãªã³ãã¥ãã±ã¼ã·ã§ã³ãè¡ãå ´åã¯çµæ§å¤§å¤ã«ãªãã¾ããã¾ããå®è¡åä½ãããã»ã¹ã«ãªããã¨ãå¤ãã®ã§ãã¿ã¹ã¯ãå¤ãå ´åããªã½ã¼ã¹æ¶è²»ãåé¡ã«ãªãå¯è½æ§ãããã¾ãã
Ractor ã®çã
Rubyã®ã¢ããã¼ã¯ããã®ããããã°ã©ãã³ã°ãã¨ããã¨ããã ã¨æãã¾ããã§ããã ããé£ãããã¨ãé¢åãªãã¨ã¯ããªãã¦ãè¯ãããã«ããã¨ããã¨æã£ã¦ãã¾ãã
ï¼ç¾å¨ãRuby ã§ãè¡ããã¨ãã§ããï¼ã¹ã¬ããããã°ã©ãã³ã°ã¯ããã®ç¹ã§èãããã¨ãããããã§ããããã°ãå ¥ãã¨ç´ãã®ãé£ããã¨ãããããã®ãããããã¯é¢ããæ©è½ã§ã¯ãªããã¨æãããã«ãªãã¾ããï¼é£ããã¹ã¬ããããã°ã©ãã³ã°ããã¡ãã¨ããããã®ããããããã¨æãã®ã§ãã¾ãä¸æ¦ã«ã¯è¨ããªãã®ã§ããï¼ããã®è©±ã¯ãæåã¡ã¢ãªç®¡çã¨èªåã¡ã¢ãªç®¡çã®è©±ã«ä¼¼ã¦ããã¨æã£ã¦ãã¾ããã¤ã¾ããã¡ããã¨ä½ãã°æåã¡ã¢ãªç®¡çã¯å¹ççã ã£ãããã¾ããããã£ããééãã¦ãã¾ã£ããããã°ã®çºè¦ã¯é£ããããã¨ãããããªã
ãã®ãããå¤å°æ§è½ãç ç²ã«ãã¦ãï¼æé«æ§è½ã¯åºãªãã«ãã¦ãï¼ããªãã¨ãªãæ¸ãã°ã¡ããã¨ä¸¦åã«åããã¨ããã®ãç®æãã¨è¯ãã®ã§ã¯ãªããã¨æããRactor ãè¨è¨ãã¦ãã¾ãã
åç¯ã§è¿°ã¹ã並å並è¡ããã°ã©ãã³ã°ã®åé¡ç¹ã解決ããããã«ãRactor ã¯ã©ã®ãããªã¢ããã¼ããã¨ã£ã¦ããããç´¹ä»ãã¾ãã
å ±æããªãããã¡ãã£ã¨å ±æãã
並åããã°ã©ãã³ã°è¨èªã«ããã¦ãããã¡ã¢ãªã«å¯¾ãã read/write ãæ··ããªããã¨ããã®ã¯å¤§äºãªè¦³ç¹ã§ãããã¨ããç´¹ä»ãã¾ããã並è¡ä¸¦åã«å®è¡ããå¦çããå ±æç¶æ ãæããªãã¨ãåé¡ãç°¡åã«ããªãããã§ãã
ããã§ãRuby ã§ãããå®ç¾ããã®ã Ractor ã§ããRactor ã¨ããåä½ã§ãªãã¸ã§ã¯ã空éããã ããããåãã¦ããäºãã«å¹²æ¸ãããªãããã«ããã¾ããããã§ãããããåææ¼ãã«ããã¹ã¬ããå®å ¨ã®åé¡ããã ãã¶è§£æ±ºããã¾ãã
ãã ããå ¨é¨åããã¨ããã»ã¹ã¨åãã§ããã¯ããã§ä¸ä¾¿ã¨ãªãã®ã§ãããããå ±æãã¦ãã ããã大ä¸å¤«ã ããã¨æããããã®ãå ±æãã¾ããããããããã»ã¹ã§å®å ¨ã«åé¢ãã¦ãã¾ããã¨ã«å¯¾ããå©ç¹ã«ãªãã¾ãã
ãã®ãã¡ãã£ã¨ã ãå ±æãããã¨ã§ãä¸è¨ã®å©ç¹ãçãã¾ãã
- Ractor éã®éä¿¡ããå°ãæ¸ãããããªã
- Ractor éã®éä¿¡ããå°ãéããªã
- Ractor éã§ã¡ã¢ãªãå ±æãããã¨ã§ãã¡ã¢ãªæ¶è²»ãæ¸ã
ã¦ã§ãã¢ããªã±ã¼ã·ã§ã³ãµã¼ãã«ããã¦ãã¹ã¬ããã¢ãã«ã好ã¾ããã®ãããã¡ã¢ãªæ¶è²»ãæ¸ããã§ã¯ãªãã§ãããããRactorã§ã¯ããã®ã¸ããããããçã£ã¦ãã¾ãã
ãã ããã¡ãã£ã¨å ±æãããã¨ã§ãã¹ã¬ããå®å ¨ã«é¢ããåé¡ãæ®ãã¾ããããã¯ãæ¬å½ã«é£ããåé¡ã§ãå©ç¹ãåããæ¬ ç¹ãåãããããã¶ãæ©ãã ã®ã§ãããä»åã¯å©ç¹ãåªå ãããã¨ã«ãã¾ããããã¾ããã ããã大ä¸å¤«ã ãããã¨ãããã¤ã§ãã
ã»ãã®è¨èªã§ã¯ãRacket ã¨ããè¨èªã§ place ã¨ãããRactor ã¨ä¼¼ã isolation ãè¡ãä»çµã¿ãããã¾ãï¼Places: adding message-passing parallelism to racket | Proceedings of the 7th symposium on Dynamic languages ï¼ãRactor ã¨ããä¼¼ã¦ãã¾ããï¼ã ãã¶åèã«ãã¾ããï¼ãéä¿¡ã®æ¹æ³ããGo è¨èªã®ããã«ããã£ã³ãã«ãç¨ããã¨ããã®ã Ractor ã¨ç°ãªãã¾ãã
Actor model 㨠CSP (Communicating Sequential Processes)
ãã Erlang 㨠Go ã®æ¯è¼ã§ãåè ã Actorãå¾è ã CSP ãæ¡ç¨ãã¦ãããã¿ãããªè©±ãããã¾ãã大éæã«è¨ãã¨ãåè ãé信対象ã並è¡å®è¡åä½ï¼ã¢ã¯ã¿ã¼ï¼ã«ãå¾è ã並è¡å®è¡åä½ãã¤ãªããã£ã³ãã«ã«å¯¾ãã¦è¡ãã®ãç¹é·ã«ãªããã¨æãã¾ãï¼å³å¯ã«ã¯å¤åéãã¨æããã§ãããããã§ã¯ããã¨ããã¦ã¿ã¾ãï¼ã
Ractor ã¯ãååã®éã Actor model ãå¼·ãæèãã¦è¨è¨ããã¦ãã¾ããå®ã¯ã2016å¹´ã®éçºå½åã§ã¯ãã¨ãã«ä½ãèããã« CSP çãªã¢ãã«ãèãã¦ãã¾ããããã ãæ°å¹´è²ã èããçµæãActor model ã®ã»ããããããªãã¨æã£ã¦ãç¾å¨ã®è¨è¨ã«ãªã£ã¦ãã¾ãã
Actor model ã®å©ç¹ã¯ã¹ã±ã¼ã«ããããããã¨ã¨è¨ããã¦ãã¾ãããããä½ã£ã¦ã¿ãã¨ããããã§ãããå¾ ã¡ãçããã®ããããããã¢ã¯ã¿ã¼ã¸éãããã¡ãã»ã¼ã¸ãåä¿¡ããæä½ã«éå®ããããã§ããããè¤æ°ã®ãã£ã³ãã«ãå¾ ã£ãããããããèªåèªèº«ã«éããã¦ããã¡ãã»ã¼ã¸ãç£è¦ããã ãã®ã»ãã楽ãªã®ã§ããä»ã«ããã³ã³ãã¼ãã³ããçã«ããããï¼ä¾ãã°ãã¢ã¯ã¿ã¼ãå¥ã®è¨ç®æ©ã«ãã¦ãããï¼ã¨ãã£ãè¯ãæ§è³ªãæã¡ã¾ãã
ãããã¾ããã®ã¸ãã Actor model åã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«ããçç±ã§ã¯ãªããä¾å¤ã®ä¼æ¬ãé©åã«è¡ããã¨ãã§ããããã¨ãã観ç¹ãããç¾å¨ã®ãã¶ã¤ã³ã«ãã¾ããã
ç¸æãæå®ããæä½ã«ããã¦ï¼å
·ä½çã«ã¯ãRactor#send
ã«ããéä¿¡æã«ãããã㯠Ractor#take
ã«ããåä¿¡æï¼ãç¸æã® Ractor ããã§ã«ä¾å¤ãªã©ã§çµäºãã¦ããå ´åãã¨ã©ã¼ã§æ°ã¥ããã¨ãã§ãã¾ããã¤ã¾ããã¨ã©ã¼ãåºã¦ãããã¨ããRactor éã§é©åã«ä¼æ¬ããããã¨ãã§ããããã§ãã
CSPã§ã¯ãå¦çã®å¯¾è±¡ããã£ã³ãã«ãªã®ã§ããã®å ã«ã¤ãªãã£ã¦ãã並è¡å®è¡åä½ã®ç¶æ³ã¯ãããã¾ããï¼ããããã¤ãªãã£ã¦ããªããããããªãï¼ãé©åã«ãã£ã³ãã«ãã¯ãã¼ãºãããã¨ããæãããã¾ãããã²ã¨æéãããã¾ãï¼ã¤ã¾ããä¸æéãå¿ããå¯è½æ§ããããããã¦å¯è½æ§ãããã°äººã¯å¿ããï¼ãã½ã±ãããªããã¯ä¼¼ããããªã¢ãã«ã§ãããããã»ã¹ã«ç´ã¥ãã¦ããã®ã§ç¸æå´ã«ç¶æ³ãä¼ããã¾ããããããã¢ãã«ã§ãããã£ãããªã¨æãã®ã§ããããã¾ããã¨ç°¡åã«æ±ãAPIã«è½ã¨ãè¾¼ãã¾ããã§ããï¼ãã£ã³ãã«ãããã«ã»ãã®Ractorã«æ¸¡ããããªç¨éã§ããã¾ããã¨ã¢ããªã³ã°ã§ãã¾ããã§ããï¼ã
ããã¤ãã®ãã¿ã¼ã³ã§ã¯ãCSP ã®ã»ããæ¸ãããããã¨ããã®ãããã£ã¦ããã®ã§ãããRactor èªä½ããã£ã³ãã«ã®ããã«ä½¿ãã°ãæ§è½ãæ°ã«ããªããã°ãå®ã¯ CSP ã¨ã»ã¼åããããªãã¨ãã§ãããã¨ãããã£ãã®ã§ãã¨ãããã Actor model 風ã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ããã¼ã¹ã«ãã¾ãããæ§è½ã¯ãã¨ã§ãªãã¨ãããããã¨æã£ã¦ãã¾ããActor ã£ã½ã push åã®ã³ãã¥ãã±ã¼ã·ã§ã³æ段ã¨ãActor ã£ã½ããªã pull åã®ã³ãã¥ãã±ã¼ã·ã§ã³æ段ãæ··ãã£ã¦ããã®ã¯ããã®è¾ºãä½ããããããããã§ãã
ä½è«ã§ãããpull åã®ã³ãã¥ãã±ã¼ã·ã§ã³ã¯ãPromise ãç°¡åã«ä½ãããã¨ãããããªæãã«ãã¦ãã¾ãã
r = Ractor.new{ expr } do_some_task() r.take # ã¡ããã©ããã¿ã¤ãã³ã°ã§å¤ãå¾ã
Promise ã«ã¯ä¸¦åã«å®è¡ãããã¨ããæå³ã¯ããã¾ããªããã§ãããRactor ã§ã¯ãããå®ç¾ãã¦ãã¾ããããã«ä½è«ã§ãããå ã»ã©ç´¹ä»ãã Racket ã® Future (Promise ã¿ãããªãã¤) ã¯ãã£ã¨ãã£ãããã¦ãã¹ã¬ããã§ä¸¦åã«åãããã ãã©ãthread-safety ãå±ããããå¦çï¼ã¤ã¾ããå ±æç¶æ ã¸ã®æä½ï¼ãæ¤åºããã¨ãããã§æ¢ã¾ãã¨ãããã£ããã奴ã«ãªã£ã¦ãã¾ãããã£ããããªããçä¼¼ããããªããã¨æãã®ã§ãããRuby ã ã¨ããããé£ããã¦æ念ãã¾ããã
ã³ãã¼ã¨ç§»å
äºãã«åé¢ãããç°å¢ã§éä¿¡ããã¨ããã³ãã¼ã«ãã£ã¦ã¡ãã»ã¼ã¸ã渡ãã®ã¯ãããããæ¹æ³ã§ãããã ãããã ãã ã¨ä»ã¨åãã§é¢ç½ããªããªãã¨æã£ã¦èãä»ããã®ã移åã§ãã
æ å ±ã®åéã«ããã¦ãéã£ãã¡ãã»ã¼ã¸ãããã®å¾åç §ã§ããªããªãã¨ãããã®ã¯ããã¾ãèãããã¨ããªãã®ã§é¢ç½ããªãã¨æã£ã¦ãGuild ã¨ãã£ã¦ãæã®ç®çæ©è½ã¨æã£ã¦ãã¾ããããããããGuild ã¨ããååã¯ãGuild ã®ã¡ã³ãã¼ã移ç±ããï¼moveããï¼ã¨ããæå³ã§è¦ã¤ããååã§ããã¾ããã
ããã¾ãæ®æ®µã¯ä½¿ããªãï¼ã³ãã¼ã§ååï¼ã¨ãããã¨ã§ããã¾ãåé¢ã«åºããªãããã«ãã¦ããããã㨠Guild ã¨ããååããªãã ããã¨ãããã¨ã§ãRactor ã«æ¹åããã¾ããã
Ractor ã使ããããã«ãªãã¾ã§ã®ãã¾ã ã¾ã é·ãéã®ã
ãã®ããã«ãã¨ããããå ¥ã£ã Ractor ã§ããã便å©ã«å©ç¨ããã«ã¯ããã¤ãã®ãã¼ãã«ãããã¾ãã
å©ç¨è ã¨ãã¦ã®èª²é¡
ã¾ãã¯ãã©ã¤ãã©ãªã®å¯¾å¿ãããããå¿ è¦ã«ãªãã¾ããã¨ãã«ãå ã«è¿°ã¹ã2ç¹
- (2) å®æ°ã«å ±æä¸å¯ãªãã¸ã§ã¯ãã®è¨å®ã»åç §
- (3) å ±æå¯è½ãªãã¸ã§ã¯ãã®ã¤ã³ã¹ã¿ã³ã¹å¤æ°ã®è¨å®ã»åç §ï¼ã¨ãã«ãã¯ã©ã¹ã»ã¢ã¸ã¥ã¼ã«ã§åé¡ã«ãªãï¼
ã«ã¤ãã¦ã¯ãã ãã¶æ¸ãæããå¿
è¦ã«ãªãã¨æãã¾ããæ¬å½ã«å¤§ä¸å¤«ããã£ã¦ãããããã¨ã説æãã¦ã¾ããã§ããããdefine_method
ã«ããã¡ã½ããå®ç¾©ã§ä½¿ããããã¯ãããµã¤ãã®ãããã¯ã ã¨ä»ã® Ractor ã§ã¯ä½¿ããªãã¨ããã®ãããã¾ããã¾ããããªç¹ã§ãã
ã©ã¤ãã©ãªããªã㨠Ruby ã®é åã¯ãã®ãããä¸ãã£ã¦ãã¾ãã¾ãããã®ããããããã®å¤æ´ã«è¿½å¾ãã¦ããã ãããã©ããããRactor ãæåãããã©ããã®å水嶺ã«ãªããã¨æãã¾ãã
使ãã¥ããã¨ãããããã°ãRactor å´ã§æ¹è¯ãããã便å©ãªã©ã¤ãã©ãªãæä¾ãã¦ãã£ãããã¦ããããã¨æãã¾ãããã£ã¼ãããã¯ããå¾ ã¡ãã¦ããã¾ãã
æ¸ãæãã¯ããããé¢åãªã®ã§ãããããã¯ãã¹ã¬ããå®å ¨ã解決ããããã®ãè¦ç´ãããã®è¯ãæéã®ä¸ã¤ã«ãªãå¯è½æ§ãããã¾ãããã¾ã¾ã§ãã¹ã¬ããå®å ¨ã«ã¤ãã¦ããã¹ãã§åé¡ãªããããªãã¨ãªãå¹³æ°ããªãã¨æã£ã¦ããã¨ãããããã£ãã大ä¸å¤«ãã¨ããå®å¿æã«ä»£ãããã§ã¯ãªããã¨æãã¾ãã
並è¡ä¸¦åå¦çæ代㮠Ruby ã«æ¸ãæããã¨ãããå人çã«ã¯ Ruby ã®æ§è³ªãå¤ãã話ãããªããã¨æãã¾ãã
å®è£ ä¸ã®èª²é¡
æåã«ãç´¹ä»ããéããæ§è½ä¸ã®åé¡ãããã¦ãã°ãæ®ã£ã¦ãã¾ããéæç´ãã¦ãããã¨æãã¾ãã®ã§ããã¡ãããã£ã¼ãããã¯é ããã°ã¨æãã¾ãã
以ä¸ãå®è£ ã®èª²é¡ã«ã¤ãã¦ãç®æ¡æ¸ãã§ä¸¦ã¹ã¦ããã¾ãã
- æ§è½æ¹å
* ObjectSpace ã®ç©ççãªåé¢ï¼åæ£GC * Fiber context ã«ãã Thread ã®å®è£ ï¼ * åä¸ããã¯ã§ã¯ãªããç´°ç²åº¦ããã¯ã«ãã並å度ã®æ¹å * ãã®ä»ããããï¼å®æ°ã¢ã¯ã»ã¹ã®ãã£ãã·ã¥ã¨ãï¼
- ãã¿ã¼ã³ã®åéã¨ã©ã¤ãã©ãªåï¼OTP, TBBçãªï¼
- ãããã°
ãããã«
æ¬ç¨¿ã§ã¯ Ractor ã«ã¤ãã¦ãç´¹ä»ãã¾ããã
èªæ ¢ããããã¨ã¯ãã¾ã ä»æ§ã»å®è£ ã¨ãã«ä¸ååã§ã¯ããã¾ãããRactor ãå°å ¥ã¾ã§ãã£ã¦ãã£ããã¨ãããããå¨ãèªè»¢è»ã«ä¹ãããã¨ã§ãã
æ°ãã Ruby ã®ä¸ã¤ã®å½¢ã¨ãããã¨ã§ã楽ããã§ããã ããã°å¹¸ãã§ãã
ã§ã¯ããããå¹´ããè¿ããã ããã