Upgrade to Pro — share decks privately, control downloads, hide ads and more …

らくらくRactor

 らくらくRactor

Fukuoka.rb 200回 LT大会 (#202)
https://fukuokarb.connpass.com/event/206956/

発表後にご指摘を頂き、22ページでMutex.newを行なっていた箇所をサンプルコードにて修正しました。
https://github.com/shioimm/til/blob/57b268151751f7f97bbc08c002d81e74fddd6732/activities/20210324_fukuoka_200/producer_consumer/thread.rb#L39

Transcript

  1. ԘҪඒ࡙!DPF@ .BS 'VLVPLBSCճ-5େձ  Β͘Β͘3BDUPS

  2. 'VLVPLBSC ͓ΊͰͱ͏͍͟͝·͢ʂ

  3. ຊ೔ͷൃදʹ͍ͭͯ ɹฒߦฒྻϓϩάϥϛϯάઈࢍษڧதͰ͢ɻ ɹٕज़తࢦఠͳͲ͓଴͍ͪͯ͠·͢ɻ 8*1

  4. ຊ೔ͷൃදʹ͍ͭͯ ɹXBSOJOH3BDUPSJTFYQFSJNFOUBM  ɹBOEUIFCFIBWJPSNBZDIBOHFJOGVUVSFWFSTJPOTPG3VCZ ɹ"MTPUIFSFBSFNBOZJNQMFNFOUBUJPOJTTVFT ɹ3BDUPS͸3VCZͷ࣮ݧతػೳͳͷͰɺ ɹࠓޙ࢓༷͕มΘΔ͔΋͠Ε·ͤΜɻ 8*1 ͱ͍͑͹ʜ

  5. ࣗݾ঺հ ԘҪඒ࡙ ͓͍͠ !DPF@  ɹ8FCϓϩάϥϚˠ ɹ'VLVPLBSCੜ·Εɺ"TBLVTBSCҭͪ ɹ࠷ۙ3VCZͷ৽ػೳɾ3BDUPS͕ؾʹͳ͍ͬͯ·͢

  6. ࣗݾ঺հ ԘҪඒ࡙ ͓͍͠ !DPF@  ɹ8FCϓϩάϥϚˠ ɹ'VLVPLBSCੜ·Εɺ"TBLVTBSCҭͪ ɹ࠷ۙ3VCZͷ৽ػೳɾ3BDUPS͕ؾʹͳ͍ͬͯ·͢ ‐ࠓ೔ͷ͓࿩

  7. 3BDUPSʹؔ͢ΔυΩϡϝϯτ 3BDUPS3VCZT"DUPSMJLFDPODVSSFOUBCTUSBDUJPO IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSEPDSBDUPSNE 3BDUPS 3VCZ%PDPSH  IUUQTSVCZEPDPSHDPSF3BDUPSIUNM 3VCZͷ3BDUPSΛࣗຫ͍ͨ͠ ΫοΫύου։ൃऀϒϩά 

    ɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ 3VCZͷ3BDUPSʹ͍ͭͯ ۜ࠲3BJMT  IUUQXXXBUEPUOFUdLPBDUJWJUJFT@HJO[BSBJMTQEG
  8. 3BDUPSʹؔ͢ΔυΩϡϝϯτ 3BDUPS3VCZT"DUPSMJLFDPODVSSFOUBCTUSBDUJPO IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSEPDSBDUPSNE 3BDUPS 3VCZ%PDPSH  IUUQTSVCZEPDPSHDPSF3BDUPSIUNM 3VCZͷ3BDUPSΛࣗຫ͍ͨ͠ ΫοΫύου։ൃऀϒϩά 

    ɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ 3VCZͷ3BDUPSʹ͍ͭͯ ۜ࠲3BJMT  IUUQXXXBUEPUOFUdLPBDUJWJUJFT@HJO[BSBJMTQEG
  9. ͨͷ͍͠ฒߦฒྻϓϩάϥϛϯά Ҿ༻ɿ3VCZͷ3BDUPSʹ͍ͭͯ ɹɹɹIUUQXXXBUEPUOFUdLPBDUJWJUJFT@HJO[BSBJMTQEG

  10. ैདྷͷ3VCZʹ૊Έࠐ·Ε͍ͯͨ5ISFBEͱൺֱͯ͠ 3BDUPS͕׎͑Δʮͨͷ͠͞ʯͱ͸ͲΜͳ΋ͷʁ

  11. ͦΕΛମݧ͢ΔͨΊɺ5ISFBEͱ3BDUPSͰ ಉ͡ॲཧΛߦ͏ϓϩάϥϜΛ ॻ͖͘Β΂ͯΈ·ͨ͠

  12. ͦΕΛମݧ͢ΔͨΊɺ5ISFBEͱ3BDUPSͰ 1SPEVDFS$POTVNFSύλʔϯΛ ॻ͖͘Β΂ͯΈ·ͨ͠ ࠓճͷίʔυ͸ҎԼʹVQ͍ͯ͠·͢ IUUQTHJUIVCDPNTIJPJNNUJMUSFFNBTUFSBDUJWJUJFT@GVLVPLB@QSPEVDFS@DPOTVNFS

  13. ࢀরɿ+BWBݴޠͰֶͿσβΠϯύλʔϯೖ໳ϚϧνεϨουฤɹ݁৓ߒஶɹୈষ1SPEVDFS$POTVNFS σʔλΛૹ৴͢Δ εϨου σʔλΛड৴͢Δ εϨου σʔλ σʔλΛ தܧ఺ʹ౉͢ 1SPEVDFS$POTVNFSύλʔϯ σʔλΛૹ৴͢ΔεϨουͱσʔλΛड৴͢ΔεϨουͷؒʹ

    தܧ఺Λઃ͚Δ͜ͱʹΑΓɺ҆શʹޮ཰Α͘σʔλΛड͚౉͢ தܧ఺ σʔλΛ தܧ఺͔ΒऔΔ ͓ޓ͍ͷεϨου͸͓ޓ͍޷͖ͳλΠϛϯάͰಈ࡞͢Δ͜ͱ͕Ͱ͖Δ
  14. ࢀরɿ+BWBݴޠͰֶͿσβΠϯύλʔϯೖ໳ϚϧνεϨουฤɹ݁৓ߒஶɹୈষ1SPEVDFS$POTVNFS σʔλ σʔλΛ தܧ఺ʹ౉͢ 1SPEVDFS$POTVNFSύλʔϯ σʔλΛૹ৴͢ΔεϨουͱσʔλΛड৴͢ΔεϨουͷؒʹ தܧ఺Λઃ͚Δ͜ͱʹΑΓɺ҆શʹޮ཰Α͘σʔλΛड͚౉͢ σʔλΛ தܧ఺͔ΒऔΔ ͓ޓ͍ͷεϨου͸͓ޓ͍޷͖ͳλΠϛϯάͰಈ࡞͢Δ͜ͱ͕Ͱ͖Δ

    1SPEVDFS $POTVNFS $IBOOFM
  15. ࠓճͷϓϩάϥϜͷྲྀΕ 1SPEVDFS $POTVNFS $IBOOFM ൪߸ σʔλʹ࠾൪͢Δ QSPEVDU σʔλΛϓʔϧ͢Δ σʔλΛ౉͢ σʔλΛऔΔ

    QSPEVDU ࠾൪ػ QSPEVDU QSPEVDU
  16. ϓϩάϥϜͷ࣮ߦ݁Ռ ྫ ᶃ1͕$IBOOFMʹOPΛ౉͢ ᶄ1͕$IBOOFMʹOPΛ౉͢ ᶅ$͕$IBOOFM͔ΒOPΛऔΔ ᶆ$͕$IBOOFM͔ΒOPΛऔΔ ᶇ1͕$IBOOFMʹOPΛ౉͢ ᶈ$͕$IBOOFM͔ΒOPΛऔΔ ᶉ1͕$IBOOFMʹOPΛ౉͢ ᶊ1͕$IBOOFMʹOPΛ౉͢

    ᶋ$͕$IBOOFM͔ΒOPΛऔΔ ʜ ͭͷ1SPEVDFSεϨουͱ̏ͭͷ$POTVNFSεϨου͕ ͦΕͧΕಉ࣌ʹಈ࡞͢Δ৔߹ͷྫ
  17. 5ISFBEΛ࢖࣮ͬͨ૷ ˞ͨͩ͠ࠓճ(7-ͷ͜ͱ͸ߟ͑ͳ͍΋ͷͱ͠·͢

  18. 5ISFBEΛ࢖͏ϓϩάϥϜͷશମ૾ class Producer # … class Consumer # … class

    Numbering # … class Channel # … channel = Channel.new(3) producers = 3.times.map { Thread.new { # … } } consumers = 3.times.map { Thread.new { # … } } producers.each(&:join) consumers.each(&:join) $IBOOFMΫϥε ࠾൪ػΫϥε 1SPEVDFSΫϥε $POTVNFSΫϥε ϝΠϯϓϩάϥϜ
  19. ϝΠϯϓϩάϥϜͷ࣮૷ channel = Channel.new(3) producers = 3.times.map { |i| Thread.new

    do Producer.new(“P-#{i + 1}”, channel).run end } consumers = 3.times.map { |i| Thread.new do Consumer.new(“C-#{i + 1}”, channel).run end } producers.each(&:join) consumers.each(&:join) QSPEVDUΛͭϓʔϧ͢Δ$IBOOFMΛੜ੒ ͭͷεϨουͰ 1SPEVDFSΦϒδΣΫτΛ ੜ੒͠ɺՔಇͤ͞Δ ͭͷεϨουͰ $POTVNFSΦϒδΣΫτΛ ੜ੒͠ɺՔಇͤ͞Δ
  20. ϝΠϯϓϩάϥϜͷ࣮૷ channel = Channel.new(3) producers = 3.times.map { |i| Thread.new

    do Producer.new(“P-#{i + 1}”, channel).run end } consumers = 3.times.map { |i| Thread.new do Consumer.new(“C-#{i + 1}”, channel).run end } producers.each(&:join) consumers.each(&:join) Ҿ਺ͱ֤ͯ͠εϨουͷ໊લͱ $IBOOFMΛ౉͢ ֤εϨουͷ࣮ߦΛ଴ͪ߹ΘͤΔ
  21. 1SPEVDFSΫϥεͷ࣮૷ class Producer def initialize(name, channel) Thread.current.name = name @channel

    = channel end def run loop do product_no = Numbering.issue @channel.put "Product no. #{product_no}" end end end ࠾൪ػ͔Β QSPEVDU൪߸Λऔಘ͢Δ ࠾൪ͨ͠QSPEVDUΛ$IBOOFMʹஔ͘ # εϨουͷ໊લΛอଘ # ChannelΦϒδΣΫτ
  22. ࠾൪ػΫϥεͷ࣮૷ class Numbering @@product_no = 0 def self.issue Mutex.new.synchronize do

    @@product_no += 1 end end end QSPEVDU൪߸ΛΧ΢ϯτΞοϓ͠ɺฦ͢ .VUFYTZODISPOJ[F ಉ࣌ʹΞΫηεͰ͖ΔͷΛ εϨουʹ੍ݶ͢Δ͜ͱͰ ةݥྖҬΛอޢ͢Δ ෳ਺ͷ1SPEVDFSεϨου͔Β ಉ࣌ʹΞΫηε͞ΕΔͨΊ ڝ߹͠ͳ͍Α͏ϩοΫΛ͔͚Δ
  23. $IBOOFMΫϥεͷ࣮૷ class Channel def initialize(size) @products = [] @size =

    size @mutex = Mutex.new @cond = ConditionVariable.new end def put(product) # … end def take # … end end 1SPEVDFSΦϒδΣΫτͷதͰݺ͹ΕΔϝιου QSPEVDUΛϓʔϧʹೖΕΔͨΊͷ΋ͷ $POTVNFSΦϒδΣΫτͷதͰݺ͹ΕΔϝιου QSPEVDUΛϓʔϧ͔ΒऔΓग़ͨ͢Ίͷ΋ͷ # mutex # ৚݅ม਺ # Channelͷϓʔϧ # Channel͕ಉ࣌ʹϓʔϧͰ͖Δ࠷େ਺
  24. $IBOOFMΫϥεͷ࣮૷ QVUϝιου class Channel def initialize(size) # … def put(product)

    @mutex.synchronize do while @products.size >= @size @cond.wait(@mutex) end # … end end def take # … end $POEJUJPO7BSJBCMFXBJU ৚͕݅ຬͨ͞ΕΔ·Ͱ NVUFYͷϩοΫΛղআ͠ɺ ॲཧΛ଴ػͤ͞Δ ϓʔϧʹۭ͖͕ͳ͍৔߹ɺ QSPEVDUΛϓʔϧʹೖΕΔ ͜ͱ͕Ͱ͖ͳ͍
  25. $IBOOFMΫϥεͷ࣮૷ QVUϝιου class Channel def initialize(size) # … def put(product)

    @mutex.synchronize do while @products.size >= @size @cond.wait(@mutex) end # … end end def take # … end ϓʔϧʹۭ͖͕ͳ͍৔߹ɺ QSPEVDUΛϓʔϧʹೖΕΔ ͜ͱ͕Ͱ͖ͳ͍ ‎৚݅ม਺Λ࢖ͬͯ ϓʔϧʹۭ͖͕Ͱ͖Δ·Ͱ ͜͜ͰॲཧΛ଴ػ͢Δ $POEJUJPO7BSJBCMFXBJU ৚͕݅ຬͨ͞ΕΔ·Ͱ NVUFYͷϩοΫΛղআ͠ɺ ॲཧΛ଴ػͤ͞Δ
  26. $IBOOFMΫϥεͷ࣮૷ QVUϝιου class Channel def initialize(size) # … def put(product)

    @mutex.synchronize do while @products.size >= @size @cond.wait(@mutex) end # … end end def take # … end ϓʔϧʹۭ͖͕Ͱ͖Δͷ͸ ͍ͭʁ
  27. class Channel def initialize(size) # … def put(product) # …

    def take @mutex.synchronize do # … product = @products.pop @cond.signal product end end end $IBOOFMΫϥεͷ࣮૷ UBLFϝιου $POTVNFSΦϒδΣΫτͷதͰ UBLFϝιου͕ݺ͹ΕΔ ‎ϓʔϧ͔ΒQSPEVDU͕औΓग़͞ΕΔ ‎ϓʔϧʹۭ͖͕Ͱ͖Δ
  28. $IBOOFMΫϥεͷ࣮૷ UBLFϝιου class Channel def initialize(size) # … def put(product)

    # … def take @mutex.synchronize do # … product = @products.pop @cond.signal product end end end $POEJUJPO7BSJBCMFTJHOBM ॲཧͷ଴ػΛղআ͠ɺ ࠶ͼϩοΫΛऔಘͰ͖ΔΑ͏ ৚݅ม਺΁௨஌ΛૹΔ ϓʔϧʹۭ͖͕Ͱ͖ͨ͜ͱΛ ৚݅ม਺΁௨஌͢Δ
  29. $IBOOFMΫϥεͷ࣮૷ UBLFϝιου class Channel def initialize(size) # … def put(product)

    # … def take @mutex.synchronize do # … product = @products.pop @cond.signal product end end end $POEJUJPO7BSJBCMFTJHOBM ॲཧͷ଴ػΛղআ͠ɺ ࠶ͼϩοΫΛऔಘͰ͖ΔΑ͏ ৚݅ม਺΁௨஌ΛૹΔ ϓʔϧʹۭ͖͕Ͱ͖ͨ͜ͱΛ ৚݅ม਺΁௨஌͢Δ ‎QVUϝιουͷ଴ػΛղআ͢Δ
  30. $IBOOFMΫϥεͷ࣮૷ ࠶ͼQVUϝιου class Channel def initialize(size) # … def put(product)

    @mutex.synchronize do while @products.size >= @size @cond.wait(@mutex) end @products.push product puts "#{Thread.current.name} produces #{product}." @cond.signal end end def take # … end  ॲཧΛ࠶։ͨ͠Β  QSPEVDUΛϓʔϧʹೖΕΔ
  31. $IBOOFMΫϥεͷ࣮૷ ࠶ͼQVUϝιου class Channel def initialize(size) # … def put(product)

    @mutex.synchronize do while @products.size >= @size @cond.wait(@mutex) end @products.push product puts "#{Thread.current.name} produces #{product}." @cond.signal end end def take # … end QVUϝιουͷதͰ΋ ৚݅ม਺΁ͷ௨஌Λߦͳ͍ͬͯΔ
  32. $IBOOFMΫϥεͷ࣮૷ ࠶ͼUBLFϝιου class Channel def initialize(size) # … def put(product)

    # … def take @mutex.synchronize do while @products.size <= 0 @cond.wait(@mutex) end product = @products.pop @cond.signal product end end end ˞UBLFϝιου͸QVUϝιουΛ ɹ൓సͤͨ͞Α͏ͳॲཧΛߦͳ͍ͬͯΔ ϓʔϧ͕ۭͰ͋Δ৔߹ɺ ϓʔϧ͔ΒQSPEVDUΛऔΔ ͜ͱ͕Ͱ͖ͳ͍ ‎৚݅ม਺Λ࢖ͬͯ ϓʔϧʹQSPEVDU͕ೖΔ·Ͱ ͜͜ͰॲཧΛ଴ػ͢Δ  ॲཧΛ࠶։ͨ͠Β  QSPEVDUΛϓʔϧ͔ΒऔΓग़͢
  33. $POTVNFSΫϥεͷ࣮૷ class Consumer def initialize(name, channel) Thread.current.name = name @channel

    = channel end def run loop do product = @channel.take puts "#{Thread.current.name} consumes #{product}." end end end # εϨουͷ໊લΛอଘ # ChannelΦϒδΣΫτ $IBOOFM͔ΒQSPEVDUΛऔΓग़͢
  34. $POTVNFSΫϥεͷ࣮૷ class Consumer def initialize(name, channel) Thread.current.name = name @channel

    = channel end def run loop do product = @channel.take puts "#{Thread.current.name} consumes #{product}." end end end $IBOOFM͔ΒQSPEVDUΛऔΓग़͢ ׬੒ʂ # εϨουͷ໊લΛอଘ # ChannelΦϒδΣΫτ
  35. 5ISFBEΛ࢖࣮ͬͨ૷ͷͨͷ͘͠ͳ͍ͱ͜Ζ ?ొ৔ਓ෺͕ଟ͍ εϨουɺNVUFYɺ৚݅ม਺  ?ϧʔϧ͕ଟ͍ ᶃσʔλ΁ͷॻ͖ࠐΈΛߦ͏ͱ͖͸ ɾڝ߹Λ๷͙ͨΊʹNVUFYΛ࢖ͬͯϩοΫΛ͔͚Δ ᶄ$IBOOFMͷঢ়ଶʹԠͯ͡৚݅ม਺ͰॲཧΛ଴ػͤ͞Δ ᶅ଴ػͤͨ͞ॲཧΛ࠶։͢Δͱ͖͸৚݅ม਺΁௨஌͢Δ

  36. 5ISFBEΛ࢖࣮ͬͨ૷ͷͨͷ͘͠ͳ͍ͱ͜Ζ ?ొ৔ਓ෺͕ଟ͍ εϨουɺNVUFYɺ৚݅ม਺  ?ϧʔϧ͕ଟ͍ ᶃσʔλ΁ͷॻ͖ࠐΈΛߦ͏ͱ͖͸ ɾڝ߹Λ๷͙ͨΊʹNVUFYΛ࢖ͬͯϩοΫΛ͔͚Δ ᶄ$IBOOFMͷঢ়ଶʹԠͯ͡৚݅ม਺ͰॲཧΛ଴ػͤ͞Δ ᶅ଴ػͤͨ͞ॲཧΛ࠶։͢Δͱ͖͸৚݅ม਺΁௨஌͢Δ ϧʔϧͷద༻࿙Ε͕͋ΔͱࠔΔʜ

    ϧʔϧΛద੾ʹద༻͢Δͷ͕೉͍͠ʜ
  37. 3BDUPSΛ࢖࣮ͬͨ૷

  38. 3BDUPSΛ࢖͏ϓϩάϥϜͷશମ૾ class Producer # … class Consumer # … channel

    = Ractor.new { # … } numbering = Ractor.new { # … } producers = 3.times.map { Ractor.new { # … } } consumers = 3.times.map { Ractor.new { # … } } producers.each(&:take) consumers.each(&:take) 1SPEVDFSΫϥε $POTVNFSΫϥε $IBOOFM3BDUPS ϝΠϯϓϩάϥϜ ࠾൪ػ3BDUPS
  39. ϝΠϯϓϩάϥϜͷ࣮૷ producers = 3.times.map { |i| Ractor.new(channel, numbering, name: "P-#{i

    + 1}") do |ch, num| Producer.new(ch, num).run end } consumers = 3.times.map { |i| Ractor.new(channel, name: "C-#{i + 1}") do |ch| Consumer.new(ch).run end } producers.each(&:take) consumers.each(&:take) ͭͷ3BDUPSͰ 1SPEVDFSΦϒδΣΫτΛ ੜ੒͠ɺՔಇͤ͞Δ ͭͷ3BDUPSͰ $POTVNFSΦϒδΣΫτΛ ੜ੒͠ɺՔಇͤ͞Δ
  40. ϝΠϯϓϩάϥϜͷ࣮૷ producers = 3.times.map { |i| Ractor.new(channel, numbering, name: "P-#{i

    + 1}") do |ch, num| Producer.new(ch, num).run end } consumers = 3.times.map { |i| Ractor.new(channel, name: "C-#{i + 1}") do |ch| Consumer.new(ch).run end } producers.each(&:take) consumers.each(&:take) ֤3BDUPSͷ࣮ߦΛ଴ͪ߹ΘͤΔ Ҿ਺ͱ֤ͯ͠3BDUPSͷ໊લͱ $IBOOFMͱ࠾൪ػΛ౉͢ Ҿ਺ͱ֤ͯ͠3BDUPSͷ໊લͱ $IBOOFMΛ౉͢
  41. 1SPEVDFSΫϥεͷ࣮૷ class Producer def initialize(channel, numbering) @channel = channel @numbering

    = numbering end def run # … end private def issue_product_no # … end end # Channel Ractor # ࠾൪ػ3BDUPS QSPEVDU൪߸Λൃߦ͢ΔͨΊͷϝιου
  42. class Producer def initialize(channel, numbering) # … def run loop

    do product_no = issue_product_no # … end end private def issue_product_no @numbering.send Ractor.current # … end end 3BDUPSTFOE ⾩SFDFJWF  ର৅ͷ3BDUPSΦϒδΣΫτ΁ ϝοηʔδΛૹΔ ࠾൪ػʹ͜ͷ3BDUPSࣗ਎ΛૹΔ 1SPEVDFSΫϥεͷ࣮૷ SVOJTTVF@QSPEVDU@OPϝιου
  43. ϝΠϯϓϩάϥϜͷ࣮૷ ࠾൪ػ3BDUPS numbering = Ractor.new(no = 0) do |no| loop

    do no += 1 producer = Ractor.receive producer.send no end end ड͚औͬͨ1SPEVDFS3BDUPSʹQSPEVDU൪߸Λฦૹ͢Δ 1SPEVDFS3BDUPSΛड͚औΔ 3BDUPSSFDFJWF ⾩TFOE  ࣗ਎ͷJODPNJOHQPSU͔Β ϝοηʔδΛड͚ೖΕΔ QSPEVDU൪߸ΛΧ΢ϯτΞοϓ͢Δ
  44. 1SPEVDFSΫϥεͷ࣮૷ SVOJTTVF@QSPEVDU@OPϝιου class Producer def initialize(channel, numbering) # … def

    run loop do product_no = issue_product_no # … end end private def issue_product_no @numbering.send Ractor.current Ractor.receive end end ࠾൪ػ͔Βड͚औͬͨQSPEVDU൪߸Λฦ͢
  45. class Producer def initialize(channel, numbering) # … def run loop

    do product_no = issue_product_no @channel.send ["Product no. #{product_no}”, Ractor.current] end end private def issue_product_no @numbering.send Ractor.current Ractor.receive end end ࠾൪ͨ͠QSPEVDUͱɺ͜ͷ3BDUPSࣗ਎Λ$IBOOFMʹૹΔ 1SPEVDFSΫϥεͷ࣮૷ SVOJTTVF@QSPEVDU@OPϝιου
  46. ϝΠϯϓϩάϥϜͷ࣮૷ $IBOOFM3BDUPS channel = Ractor.new do loop do product, producer

    = Ractor.receive puts “#{producer.name} produces #{product}." Ractor.yield product end end 3BDUPSZJFME ⾩UBLF  ࣗ਎ͷPVUHPJOHQPSU͔Β ϝοηʔδΛૹΓग़͢ 1SPEVDFS3BDUPS͔ΒσʔλΛड͚औͬͯ ͦͷ··$POTVNFS3BDUPS΁ૹΓग़͚ͩ͢ʂ QSPEVDUΛૹΓग़͢ QSPEVDUΛड͚औΔ
  47. $POTVNFSΫϥεͷ࣮૷ class Consumer def initialize(channel) @channel = channel end def

    run loop do product = @channel.take puts "#{Ractor.current.name} consumes #{product}" end end end 3BDUPSUBLF ⾩ZJFME  ର৅ͷ3BDUPSΦϒδΣΫτ͔Β ϝοηʔδΛҾ͖ग़͢ # Channel Ractor $IBOOFM͔ΒૹΓग़͞ΕͨQSPEVDUΛड͚औΔ
  48. $POTVNFSΫϥεͷ࣮૷ class Consumer def initialize(channel) @channel = channel end def

    run loop do product = @channel.take puts "#{Ractor.current.name} consumes #{product}" end end end 3BDUPSUBLF ⾩ZJFME  ର৅ͷ3BDUPSΦϒδΣΫτ͔Β ϝοηʔδΛҾ͖ग़͢ ׬੒ʂ # Channel Ractor $IBOOFM͔ΒૹΓग़͞ΕͨQSPEVDUΛड͚औΔ
  49. 3BDUPSΛ࢖࣮ͬͨ૷ͷͨͷ͍͠ͱ͜Ζ ✔ొ৔ਓ෺͸3BDUPS͚ͩͳͷͰΒ͘Β࣮͘૷Ͱ͖Δ ✔ϧʔϧ͕γϯϓϧͳͷͰΒ͘Β࣮͘૷Ͱ͖Δ ʮ3BDUPS͸3BDUPS͔ΒϝοηʔδΛͻͱͭड͚औΔ ʮ3BDUPS͸3BDUPS΁ϝοηʔδΛͻͱͭૹΔʯ ڝ߹͕ൃੜ͠ͳ͍ $IBOOFM͕ঢ়ଶΛ࣋ͨͳ͍ ✔3BDUPSಉ࢜Λ૊Έ߹Θͤͯ ϓϩάϥϜΛߟ͑Δͷ͕ͨͷ͍͠ʂ ‎

  50. 3BDUPSΛ࢖࣮ͬͨ૷ͷͨͷ͍͠ͱ͜Ζ ✔ొ৔ਓ෺͸3BDUPS͚ͩͳͷͰΒ͘Β࣮͘૷Ͱ͖Δ ✔ϧʔϧ͕γϯϓϧͳͷͰΒ͘Β࣮͘૷Ͱ͖Δ ʮ3BDUPS͸3BDUPS͔ΒϝοηʔδΛͻͱͭड͚औΔ ʮ3BDUPS͸3BDUPS΁ϝοηʔδΛͻͱͭૹΔʯ ڝ߹͕ൃੜ͠ͳ͍ $IBOOFM͕ঢ়ଶΛ࣋ͨͳ͍ ✔3BDUPSಉ࢜Λ૊Έ߹Θͤͯ ϓϩάϥϜΛߟ͑Δͷ͕ͨͷ͍͠ʂ ॏཁ

  51. ͓ർΕ༷Ͱͨ͠

  52. ༨ஊ ࡢ೥य़ɺ3VCZ͞Έͬͱʹͯ

  53. ༨ஊ ࡢ೥य़ɺ3VCZ͞Έͬͱʹͯ

  54. ෬ઢճऩEPOF Ұ೥ӽ͠Ͱ ༨ஊ ࡢ೥य़ɺ3VCZ͞Έͬͱʹͯ

  55. ·ͱΊ 3BDUPSͰ ฒߦฒྻϓϩάϥϛϯάΛ Β͘Βͨ͘ͷ͠ΜͰ͍͖·͠ΐ͏ʂ

  56. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠