rabbit-slide-shugo-MatsueRubyKaigi09 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/README.md +8 -0
- data/Rakefile +17 -0
- data/config.yaml +19 -0
- data/implement-thread-in-ruby.md +200 -0
- data/pdf/MatsueRubyKaigi09-implement-thread-in-ruby.pdf +0 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 355deb1420bc1c0e8eebed8d76ec7bfb0d27364fd2008051023a9ef56a29097c
|
4
|
+
data.tar.gz: 8c3df14bd6cc416f391fb6125525db472c2e4e016d7150ed5f6c01df551aa28d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc3cc8f79d6f910051767314f8e2eceec1eb117039e0cb9392edc6e264551cd0fd4d1d09e08dc4e810b8698d913f6dbc51b12c6338c4aab05b7f64ff3cdaab8a
|
7
|
+
data.tar.gz: 82ff10d4e7479bbf09681fa84f8df4b2dca5677be08b32a67ef9d53ecedcc362b0e045b2eb84aecf5eaed673a428bf60f363125cdb48a1cde9a20cf381362558
|
data/.rabbit
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
implement-thread-in-ruby.md
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rabbit/task/slide"
|
2
|
+
|
3
|
+
# Edit ./config.yaml to customize meta data
|
4
|
+
|
5
|
+
spec = nil
|
6
|
+
Rabbit::Task::Slide.new do |task|
|
7
|
+
spec = task.spec
|
8
|
+
# spec.files += Dir.glob("doc/**/*.*")
|
9
|
+
# spec.files -= Dir.glob("private/**/*.*")
|
10
|
+
spec.add_runtime_dependency("rabbit-theme-lightning-night-black")
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Tag #{spec.version}"
|
14
|
+
task :tag do
|
15
|
+
sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
|
16
|
+
sh("git", "push", "--tags")
|
17
|
+
end
|
data/config.yaml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
---
|
2
|
+
id: MatsueRubyKaigi09
|
3
|
+
base_name: implement-thread-in-ruby
|
4
|
+
tags: []
|
5
|
+
presentation_date:
|
6
|
+
version: 1.0.0
|
7
|
+
licenses: []
|
8
|
+
slideshare_id:
|
9
|
+
speaker_deck_id:
|
10
|
+
ustream_id:
|
11
|
+
vimeo_id:
|
12
|
+
youtube_id:
|
13
|
+
author:
|
14
|
+
markup_language: :markdown
|
15
|
+
name: Shugo Maeda
|
16
|
+
email: shugo@ruby-lang.org
|
17
|
+
rubygems_user: shugo
|
18
|
+
slideshare_user: ShugoMaeda
|
19
|
+
speaker_deck_user:
|
@@ -0,0 +1,200 @@
|
|
1
|
+
# Rubyでつくる\\nスレッド
|
2
|
+
|
3
|
+
author
|
4
|
+
: Shugo Maeda
|
5
|
+
|
6
|
+
institution
|
7
|
+
: NaCl
|
8
|
+
|
9
|
+
date
|
10
|
+
: 2018-06-30
|
11
|
+
|
12
|
+
theme
|
13
|
+
: lightning-night-black
|
14
|
+
|
15
|
+
allotted-time
|
16
|
+
: 5m
|
17
|
+
|
18
|
+
# やりたいこと
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
MinThread.start do
|
22
|
+
20.times do |i|
|
23
|
+
puts "Thread#1: #{i}"
|
24
|
+
sleep(0.1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
MinThread.start do
|
29
|
+
20.times do |i|
|
30
|
+
puts "Thread#2: #{i}"
|
31
|
+
sleep(0.1)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
# 継続(Continuation)
|
37
|
+
|
38
|
+
* 次に実行される計算を表す
|
39
|
+
* グローバルgoto
|
40
|
+
* オブジェクトの状態は戻らない
|
41
|
+
* Ruby 1.8のスレッドの実装を利用
|
42
|
+
* [ruby-dev:4083]
|
43
|
+
* 継続でスレッドをつくれるのでは?
|
44
|
+
|
45
|
+
# わかる人にはわかる説明(1)
|
46
|
+
|
47
|
+
* Ruby 1.8のスレッドはsetjmp()/longjmp()で切り替える
|
48
|
+
* スタックは自前で保存して書き戻す
|
49
|
+
* 継続も同じ仕組み
|
50
|
+
|
51
|
+
# わかる人にはわかる説明(2)
|
52
|
+
|
53
|
+
|スレッド|並行宇宙|
|
54
|
+
|継続|世界線|
|
55
|
+
|
56
|
+
# 継続の例
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
require "continuation"
|
60
|
+
callcc {|c| $cont = c}
|
61
|
+
print "Hello, World!\n"
|
62
|
+
$cont.call
|
63
|
+
```
|
64
|
+
|
65
|
+
# 実装
|
66
|
+
|
67
|
+
# スレッドの作成
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
module MinThread
|
71
|
+
QUEUE = []
|
72
|
+
|
73
|
+
def self.start(&block)
|
74
|
+
QUEUE.push(block)
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
# スレッドの実行
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
def self.resume
|
82
|
+
proc = QUEUE.shift
|
83
|
+
if proc
|
84
|
+
proc.call
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
at_exit do
|
89
|
+
MinThread.resume
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
# スレッドの切替
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
def self.pass
|
97
|
+
callcc do |c|
|
98
|
+
start do
|
99
|
+
c.call
|
100
|
+
end
|
101
|
+
resume
|
102
|
+
end
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
# 動いた!
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
MinThread.start do
|
110
|
+
20.times do |i|
|
111
|
+
puts "Thread#1: #{i}"
|
112
|
+
sleep(0.1)
|
113
|
+
MinThread.pass
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
MinThread.start do
|
118
|
+
20.times do |i|
|
119
|
+
puts "Thread#2: #{i}"
|
120
|
+
sleep(0.1)
|
121
|
+
MinThread.pass
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
# でも何か違う
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
MinThread.start do
|
130
|
+
20.times do |i|
|
131
|
+
puts "Thread#1: #{i}"
|
132
|
+
sleep(0.1)
|
133
|
+
MinThread.pass # これが必要
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
MinThread.start do
|
138
|
+
20.times do |i|
|
139
|
+
puts "Thread#2: #{i}"
|
140
|
+
sleep(0.1)
|
141
|
+
MinThread.pass # これが必要
|
142
|
+
end
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
# 勝手にスレッドを切り替えたい
|
147
|
+
|
148
|
+
# TracePoint
|
149
|
+
|
150
|
+
* Ruby実行中のイベントをフック
|
151
|
+
* フックで切り替えればいいのでは?
|
152
|
+
|
153
|
+
# 実装
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
at_exit do
|
157
|
+
MinThread.set_next_switch_time
|
158
|
+
TracePoint.trace(:line) do |tp|
|
159
|
+
MinThread.schedule # 一定時間毎にThread.pass
|
160
|
+
end
|
161
|
+
MinThread.resume
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
# 1回しか切り替わらない!
|
166
|
+
|
167
|
+
# 理由
|
168
|
+
|
169
|
+
* フックの中ではTracePointが無効化される
|
170
|
+
* フック中で継続を呼ぶと無効化されたまま
|
171
|
+
|
172
|
+
# じゃあモンキーパッチで
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
at_exit do
|
176
|
+
MinThread.set_next_switch_time
|
177
|
+
[Integer, String, Array, Hash, IO, File].each do |mod|
|
178
|
+
mod.prepend Module.new {
|
179
|
+
mod.instance_methods(false).each do |method|
|
180
|
+
define_method(method) do |*args, &block|
|
181
|
+
MinThread.schedule
|
182
|
+
super(*args, &block)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
}
|
186
|
+
end
|
187
|
+
MinThread.resume
|
188
|
+
end
|
189
|
+
```
|
190
|
+
|
191
|
+
# デモ
|
192
|
+
|
193
|
+
# 課題
|
194
|
+
|
195
|
+
* IOなどでブロックすると全部止まる
|
196
|
+
* IO#readなどをノンブロッキングIOで再実装すればいい
|
197
|
+
|
198
|
+
# まとめ
|
199
|
+
|
200
|
+
* スレッドはつくれる
|
Binary file
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-shugo-MatsueRubyKaigi09
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shugo Maeda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rabbit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rabbit-theme-lightning-night-black
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: |-
|
42
|
+
* [スライド原稿](implement-thread-in-ruby.md)
|
43
|
+
* [スライドPDF](pdf/MatsueRubyKaigi09-implement-thread-in-ruby.pdf)
|
44
|
+
* [ベース実装](minthread.rb)
|
45
|
+
* [TracePoint版実装](minthread2.rb)
|
46
|
+
* [モンキーパッチ版実装](minthread3.rb)
|
47
|
+
email:
|
48
|
+
- shugo@ruby-lang.org
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- ".rabbit"
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- config.yaml
|
57
|
+
- implement-thread-in-ruby.md
|
58
|
+
- pdf/MatsueRubyKaigi09-implement-thread-in-ruby.pdf
|
59
|
+
homepage: http://slide.rabbit-shocker.org/authors/shugo/MatsueRubyKaigi09/
|
60
|
+
licenses: []
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 3.0.0.beta1
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Rubyでつくるスレッド
|
82
|
+
test_files: []
|