Skip to content

Instantly share code, notes, and snippets.

@hiroeorz
Created May 7, 2014 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiroeorz/4a937d2d5386ce81a440 to your computer and use it in GitHub Desktop.
Save hiroeorz/4a937d2d5386ce81a440 to your computer and use it in GitHub Desktop.
ツナでもわかるmruby [6回目:コルーチン・非同期I/O] ref: http://qiita.com/hiroeorz@github/items/68acf89b768475af6e2c
MRuby::Build.new do |conf|
...
conf.gem :github => 'mattn/mruby-uv' #追加
...
end
fiber = Fiber.new{ # ①Fiber生成
counter = 0 # ②counter変数を初期化
loop do
puts "top of loop"
Fiber.yield(counter) # ③コンテキストを親へ戻す ⑦コンテキストを親へ戻す
counter += 1 # ⑥counter変数に1を足す
end
}
# ④コンテキストが子から戻る
5.times do
count = fiber.resume # ⑤コンテキストを子へ切り替える
# ⑧コンテキストが子から戻り、返り値をcount変数に代入
p count # ⑨子から受け取った値を表示
end
fiber = Fiber.new{ # ①Fiber生成
counter = 0 # ②counter初期化
loop do
name, arg = Fiber.yield(counter) # ③親へコンテキストを移す
# ⑥name,argと共に子へコンテキストが移る
puts "called: #{name}(#{arg})"
case name # ⑦受け取ったnameによって処理を切り替える
when :+ # ⑧nameが:+の場合counterにargを足す
counter += arg
when :- # ⑨nameが:-の場合counterからargを引く
counter -= arg
when :clear # ⑩nameが:clearの場合はcounterを0で初期化
counter = 0
end
end
}
fiber.resume # ④一回ループを回しておく
5.times do
count = fiber.resume([:+, 2]) # ⑤counterに2を足す
# ⑪結果をcount変数に代入
p count
count = fiber.resume([:-, 1]) # ⑫counterから1を引く
p count
end
count = fiber.resume(:clear)
p count
mruby fiber-sample.rb
top of loop
0
top of loop
1
top of loop
2
top of loop
3
top of loop
4
$ mruby tcp-server.rb
bound to 0.0.0.0:6789
$ mruby tcp-client.rb
hello world
$ mruby tcp-server-client.rb
bound to 0.0.0.0:16789
hello world
hello world
hello world
hello world
hello world
hello world
...
$ mruby fiber-sample2.rb
called: +(2)
2
called: -(1)
1
called: +(2)
3
called: -(1)
2
called: +(2)
4
called: -(1)
3
called: +(2)
5
called: -(1)
4
called: +(2)
6
called: -(1)
5
called: clear()
0
$ brew install libtool
$ brew install automake
$ rake
$ sudo cp ./bin/* /usr/local/mruby/bin/
$ mruby tcp-server.rb
bound to 0.0.0.0:6789
$ telnet localhost 6789
Trying 127.0.0.1...
Connected to localhost.
hello world
Connection closed by foreign host.
client = UV::TCP.new
client.connect(UV.ip4_addr("127.0.0.1", 6789)) {|x|
if x == 0
client.read_start { |b|
puts b.to_s
}
else
client.close
end
}
UV::run()
# サーバー
server = UV::TCP.new
server.bind(UV::ip4_addr("0.0.0.0", 16789))
puts "bound to #{server.getsockname}"
server.listen(5) { |x|
return if x != 0
c = server.accept;
timer = UV::Timer.new # サーバーから一定間隔でデータを送るためのタイマー
timer.start(1000, 1000) { |x|
begin
c.write "hello world\r\n"
rescue UVError
c.close
timer.stop
c = timer = nil
end
}
}
# クライアント
client = UV::TCP.new
client.connect(UV.ip4_addr("127.0.0.1", 16789)) {|x|
if x == 0
client.read_start { |b|
puts b.to_s
}
else
client.close
end
}
UV::run()
s = UV::TCP.new
s.bind(UV::ip4_addr("0.0.0.0", 6789))
puts "bound to #{s.getsockname}"
s.listen(5) {|x|
return if x != 0
c = s.accept;
c.write "hello world\r\n"
c.close
}
UV::run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment