Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rubyでつくるスレッド
Search
Shugo Maeda
June 30, 2018
Programming
0
980
Rubyでつくるスレッド
松江Ruby会議09のLTで、callccを使ってスレッドを実装する話をしました。
Shugo Maeda
June 30, 2018
Tweet
Share
More Decks by Shugo Maeda
See All by Shugo Maeda
Refining refinements
shugo
1
250
Other Decks in Programming
See All in Programming
Site Reliability Engineering for GMO
pyama86
8
1.1k
Scalable Customer Journey Orchestration (CJO)
lewuathe
0
420
SIMD Parallel Programming with the Vector API
josepaumard
0
230
Let's learn code review
riofujimon
2
590
Node.js v22 で変わること
yosuke_furukawa
PRO
12
4k
Compose-View Interop in Practice (mDevCamp 2024)
stewemetal
0
170
Try creating your own orderedmap
kazamori
1
220
はてなにおける CSS Modules、及び CSS Modules に足りないもの / CSS Modules in Hatena, and CSS Modules missing parts
mizdra
7
990
Sheets API使ってみた
toshi0383
2
170
Documentation for users with AsciiDoc and Antora
ahus1
0
370
Goのエラースタックトレースの歴史と今後
sonatard
10
1.8k
Java 22 Overview
kishida
1
200
Featured
See All Featured
Facilitating Awesome Meetings
lara
43
5.6k
In The Pink: A Labor of Love
frogandcode
138
21k
Creatively Recalculating Your Daily Design Routine
revolveconf
211
11k
StorybookのUI Testing Handbookを読んだ
zakiyama
13
4.6k
What's new in Ruby 2.0
geeforr
337
31k
Code Reviewing Like a Champion
maltzj
515
39k
The Cult of Friendly URLs
andyhume
74
5.7k
Why You Should Never Use an ORM
jnunemaker
PRO
51
8.7k
Rails Girls Zürich Keynote
gr2m
91
13k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
123
39k
The Mythical Team-Month
searls
217
42k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
34
8.9k
Transcript
Rubyでつくる スレッド Shugo Maeda NaCl 2018-06-30
やりたいこと MinThread.start do 20.times do |i| puts "Thread#1: #{i}" sleep(0.1)
end end MinThread.start do 20.times do |i| puts "Thread#2: #{i}" sleep(0.1) end end
継続(Continuation) 次に実行される計算を表す グローバルgoto オブジェクトの状態は戻らない Ruby 1.8のスレッドの実装を利用 [ruby-dev:4083] 継続でスレッドをつくれるのでは?
わかる人にはわかる説明(1) Ruby 1.8のスレッドはsetjmp()/ longjmp()で切り替える スタックは自前で保存して書き戻す 継続も同じ仕組み
わかる人にはわかる説明(2) スレッド 並行宇宙 継続 世界線
継続の例 require "continuation" callcc {|c| $cont = c} print "Hello,
World!\n" $cont.call
実装
スレッドの作成 module MinThread QUEUE = [] def self.start(&block) QUEUE.push(block) end
スレッドの実行 def self.resume proc = QUEUE.shift if proc proc.call end
end at_exit do MinThread.resume end
スレッドの切替 def self.pass callcc do |c| QUEUE.push(c) resume end end
動いた! MinThread.start do 20.times do |i| puts "Thread#1: #{i}" sleep(0.1)
MinThread.pass end end MinThread.start do 20.times do |i| puts "Thread#2: #{i}" sleep(0.1) MinThread.pass end end
でも何か違う MinThread.start do 20.times do |i| puts "Thread#1: #{i}" sleep(0.1)
MinThread.pass # これが必要 end end MinThread.start do 20.times do |i| puts "Thread#2: #{i}" sleep(0.1) MinThread.pass # これが必要 end end
勝手にスレッドを切り替えたい
TracePoint Ruby実行中のイベントをフック フックで切り替えればいいのでは?
実装 at_exit do MinThread.set_next_switch_time TracePoint.trace(:line) do |tp| MinThread.schedule # 一定時間毎にThread.pass
end MinThread.resume end
1回しか切り替わらない!
理由 フックの中ではTracePointが無効 化される フック中で継続を呼ぶと無効化され たまま
じゃあモンキーパッチで at_exit do MinThread.set_next_switch_time [Integer, String, Array, Hash, IO, File].each
do |mod| mod.prepend Module.new { mod.instance_methods(false).each do |method| define_method(method) do |*args, &block| MinThread.schedule super(*args, &block) end end } end MinThread.resume end
デモ
課題 IOなどでブロックすると全部止まる IO#readなどをノンブロッキングIOで再実 装すればいい
まとめ スレッドはつくれる