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

More Decks by Misaki Shioi(塩井美咲/しおい)

Other Decks in Programming

Transcript

  1. ԘҪඒ࡙[email protected]
    .BS
    'VLVPLBSCճ-5େձ

    Β͘Β͘3BDUPS

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. ࣗݾ঺հ
    ԘҪඒ࡙ ͓͍͠
    [email protected]

    ɹ8FCϓϩάϥϚˠ
    ɹ'VLVPLBSCੜ·Εɺ"TBLVTBSCҭͪ
    ɹ࠷ۙ3VCZͷ৽ػೳɾ3BDUPS͕ؾʹͳ͍ͬͯ·͢

    View Slide

  6. ࣗݾ঺հ
    ԘҪඒ࡙ ͓͍͠
    [email protected]

    ɹ8FCϓϩάϥϚˠ
    ɹ'VLVPLBSCੜ·Εɺ"TBLVTBSCҭͪ
    ɹ࠷ۙ3VCZͷ৽ػೳɾ3BDUPS͕ؾʹͳ͍ͬͯ·͢
    ‐ࠓ೔ͷ͓࿩

    View Slide

  7. 3BDUPSʹؔ͢ΔυΩϡϝϯτ
    3BDUPS3VCZT"DUPSMJLFDPODVSSFOUBCTUSBDUJPO
    IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSEPDSBDUPSNE
    3BDUPS 3VCZ%PDPSH

    IUUQTSVCZEPDPSHDPSF3BDUPSIUNM
    3VCZͷ3BDUPSΛࣗຫ͍ͨ͠ ΫοΫύου։ൃऀϒϩά

    ɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ
    3VCZͷ3BDUPSʹ͍ͭͯ ۜ࠲3BJMT

    [email protected][BSBJMTQEG

    View Slide

  8. 3BDUPSʹؔ͢ΔυΩϡϝϯτ
    3BDUPS3VCZT"DUPSMJLFDPODVSSFOUBCTUSBDUJPO
    IUUQTHJUIVCDPNSVCZSVCZCMPCNBTUFSEPDSBDUPSNE
    3BDUPS 3VCZ%PDPSH

    IUUQTSVCZEPDPSHDPSF3BDUPSIUNM
    3VCZͷ3BDUPSΛࣗຫ͍ͨ͠ ΫοΫύου։ൃऀϒϩά

    ɹIUUQTUFDIMJGFDPPLQBEDPNFOUSZ
    3VCZͷ3BDUPSʹ͍ͭͯ ۜ࠲3BJMT

    [email protected][BSBJMTQEG

    View Slide

  9. ͨͷ͍͠ฒߦฒྻϓϩάϥϛϯά
    Ҿ༻ɿ3VCZͷ3BDUPSʹ͍ͭͯ
    ɹɹɹ[email protected][BSBJMTQEG

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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εϨου͕
    ͦΕͧΕಉ࣌ʹಈ࡞͢Δ৔߹ͷྫ

    View Slide

  17. 5ISFBEΛ࢖࣮ͬͨ૷
    ˞ͨͩ͠ࠓճ(7-ͷ͜ͱ͸ߟ͑ͳ͍΋ͷͱ͠·͢

    View Slide

  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Ϋϥε
    ϝΠϯϓϩάϥϜ

    View Slide

  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ΦϒδΣΫτΛ
    ੜ੒͠ɺՔಇͤ͞Δ

    View Slide

  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Λ౉͢
    ֤εϨουͷ࣮ߦΛ଴ͪ߹ΘͤΔ

    View Slide

  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ΦϒδΣΫτ

    View Slide

  22. ࠾൪ػΫϥεͷ࣮૷
    class Numbering

    @@product_no = 0

    def self.issue

    Mutex.new.synchronize do

    @@product_no += 1

    end

    end

    end

    QSPEVDU൪߸ΛΧ΢ϯτΞοϓ͠ɺฦ͢
    .VUFYTZODISPOJ[F
    ಉ࣌ʹΞΫηεͰ͖ΔͷΛ
    εϨουʹ੍ݶ͢Δ͜ͱͰ
    ةݥྖҬΛอޢ͢Δ
    ෳ਺ͷ1SPEVDFSεϨου͔Β
    ಉ࣌ʹΞΫηε͞ΕΔͨΊ
    ڝ߹͠ͳ͍Α͏ϩοΫΛ͔͚Δ

    View Slide

  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͕ಉ࣌ʹϓʔϧͰ͖Δ࠷େ਺

    View Slide

  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ΛϓʔϧʹೖΕΔ
    ͜ͱ͕Ͱ͖ͳ͍

    View Slide

  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ͷϩοΫΛղআ͠ɺ
    ॲཧΛ଴ػͤ͞Δ

    View Slide

  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
    ϓʔϧʹۭ͖͕Ͱ͖Δͷ͸
    ͍ͭʁ

    View Slide

  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͕औΓग़͞ΕΔ
    ‎ϓʔϧʹۭ͖͕Ͱ͖Δ

    View Slide

  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
    ॲཧͷ଴ػΛղআ͠ɺ
    ࠶ͼϩοΫΛऔಘͰ͖ΔΑ͏
    ৚݅ม਺΁௨஌ΛૹΔ
    ϓʔϧʹۭ͖͕Ͱ͖ͨ͜ͱΛ
    ৚݅ม਺΁௨஌͢Δ

    View Slide

  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ϝιουͷ଴ػΛղআ͢Δ

    View Slide

  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ΛϓʔϧʹೖΕΔ

    View Slide

  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ϝιουͷதͰ΋
    ৚݅ม਺΁ͷ௨஌Λߦͳ͍ͬͯΔ

    View Slide

  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Λϓʔϧ͔ΒऔΓग़͢

    View Slide

  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ΛऔΓग़͢

    View Slide

  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ΦϒδΣΫτ

    View Slide

  35. 5ISFBEΛ࢖࣮ͬͨ૷ͷͨͷ͘͠ͳ͍ͱ͜Ζ
    ?ొ৔ਓ෺͕ଟ͍ εϨουɺNVUFYɺ৚݅ม਺

    ?ϧʔϧ͕ଟ͍
    ᶃσʔλ΁ͷॻ͖ࠐΈΛߦ͏ͱ͖͸
    ɾڝ߹Λ๷͙ͨΊʹNVUFYΛ࢖ͬͯϩοΫΛ͔͚Δ
    ᶄ$IBOOFMͷঢ়ଶʹԠͯ͡৚݅ม਺ͰॲཧΛ଴ػͤ͞Δ
    ᶅ଴ػͤͨ͞ॲཧΛ࠶։͢Δͱ͖͸৚݅ม਺΁௨஌͢Δ

    View Slide

  36. 5ISFBEΛ࢖࣮ͬͨ૷ͷͨͷ͘͠ͳ͍ͱ͜Ζ
    ?ొ৔ਓ෺͕ଟ͍ εϨουɺNVUFYɺ৚݅ม਺

    ?ϧʔϧ͕ଟ͍
    ᶃσʔλ΁ͷॻ͖ࠐΈΛߦ͏ͱ͖͸
    ɾڝ߹Λ๷͙ͨΊʹNVUFYΛ࢖ͬͯϩοΫΛ͔͚Δ
    ᶄ$IBOOFMͷঢ়ଶʹԠͯ͡৚݅ม਺ͰॲཧΛ଴ػͤ͞Δ
    ᶅ଴ػͤͨ͞ॲཧΛ࠶։͢Δͱ͖͸৚݅ม਺΁௨஌͢Δ
    ϧʔϧͷద༻࿙Ε͕͋ΔͱࠔΔʜ
    ϧʔϧΛద੾ʹద༻͢Δͷ͕೉͍͠ʜ

    View Slide

  37. 3BDUPSΛ࢖࣮ͬͨ૷

    View Slide

  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

    View Slide

  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ΦϒδΣΫτΛ
    ੜ੒͠ɺՔಇͤ͞Δ

    View Slide

  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Λ౉͢

    View Slide

  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൪߸Λൃߦ͢ΔͨΊͷϝιου

    View Slide

  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Ϋϥεͷ࣮૷ [email protected]@OPϝιου

    View Slide

  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൪߸ΛΧ΢ϯτΞοϓ͢Δ

    View Slide

  44. 1SPEVDFSΫϥεͷ࣮૷ [email protected]@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൪߸Λฦ͢

    View Slide

  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Ϋϥεͷ࣮૷ [email protected]@OPϝιου

    View Slide

  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Λड͚औΔ

    View Slide

  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Λड͚औΔ

    View Slide

  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Λड͚औΔ

    View Slide

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

    View Slide

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


    View Slide

  51. ͓ർΕ༷Ͱͨ͠

    View Slide

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

    View Slide

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

    View Slide

  54. ෬ઢճऩEPOF Ұ೥ӽ͠Ͱ

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

    View Slide

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

    View Slide

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

    View Slide