More Related Content
PPTX
PPTX
PDF
Linux Kernel vs DPDK: HTTP Performance Showdown PPTX
PPT
PPTX
PPTX
C#や.NET Frameworkがやっていること PDF
Understand and optimize Linux I/O What's hot
PDF
PDF
Kyoto Tycoon Guide in Japanese PDF
PDF
PPTX
PPTX
C#を始めたばかりの人へのLINQ to Objects PDF
PDF
PPT
PDF
The Microkernel Mach Under NeXTSTEP PPTX
PDF
PDF
PDF
PDF
PDF
PDF
高位合成ツールVivado hlsのopen cv対応 PDF
PPTX
PDF
Viewers also liked
PDF
PDF
PDF
PDF
How to measure UIView position on Native App PDF
Isucon makers casual talks KEY
PDF
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 - PPTX
Similar to Em synchrony について
PDF
18166746-NeverBlock-RubyKaigi2009 PDF
PPTX
PPTX
Async Programming on Ruby PDF
大江戸Ruby会議01 "mission critical"なシステムでも使えるThreadの作り方 PDF
node+socket.io+enchant.jsでチャットゲーを作る PDF
PDF
PPTX
Elixir入門「第2回:PC間で通信するアプリをサクっと書いてみる」 PDF
KEY
難しそうで難しくない少し難しいClojure並行処理 PDF
Rubyで創るOpenFlowネットワーク - LLまつり KEY
PPT
PPTX
Elixir入門「第5回:Visualixirで見るマルチプロセス」 PPTX
PPT
PPT
PDF
PDF
More from Tomoya Kawanishi
PPTX
PDF
ENECHANGE社での Scout APM 利用事例 PDF
PDF
PDF
Ruby on Rails のキャッシュ機構について PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
PDF
Active record query interface PDF
Active Support のコア拡張機能について PDF
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー PDF
PDF
PDF
Recently uploaded
PDF
第25回FA設備技術勉強会_自宅で勉強するROS・フィジカルAIアイテム.pdf PDF
visionOS TC「新しいマイホームで過ごすApple Vision Proとの新生活」 PPTX
PDF
基礎から学ぶ PostgreSQL の性能監視 (PostgreSQL Conference Japan 2025 発表資料) PDF
安価な ロジック・アナライザを アナライズ(?),Analyze report of some cheap logic analyzers PDF
PCCC25(設立25年記念PCクラスタシンポジウム):東京大学情報基盤センター テーマ1/2/3「Society5.0の実現を目指す『計算・データ・学習... Em synchrony について
- 1.
- 2.
自己紹介 1
cuzic といいます
きゅーじっく と読みます
Ruby 暦は かれこれもう10年くらい
近況
Nook Simple Touch というデバイスを買いました
Android 2.1 が動く、ディスプレイが e-ink の端末
定期巡回している Web 記事を快適に読めてしあわせ
今後の勉強会予定
8月20日(土) Coders At Work 読書会 #2
今回と同じ会場です
2週間後!
みんな来てください。
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 3.
今日の議題 2
• 複数処理の同時並行実行について
• マルチスレッドによる同時並行処理
従来の
• IO多重化 による同時並行処理
並列処理
• eventmachine とは
event- • コールバック登録による非同期処理
machine
• Fiber とは
em- • 非同期処理の逐次処理的な記述
synchrony
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 4.
同時並行で処理を進めて高速化したい! 3
過剰な待ち時間のために、動作が遅かったりします
例) WEBダウンロード
ネットワークIO の待ち時間の間は CPU は働きません
CPU としては軽い処理なのに、もったいない!
⇒ 多数の URL からのダウンロードであれば、同時並行で
ダウンロードさせれば、高速化可能。
同時に処理させる方法の例
マルチスレッド
スレッド特有の問題が多数存在
(排他制御、デッドロック、変数の同期 etc)
IO 多重化(select(2) の利用など)
状態の管理が大変。慣れるまでは苦労する。
マルチプロセス
今回は説明しません
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 5.
マルチスレッドによる同時並行処理 4
マルチスレッドの長所 require 'open-uri'
書きやすい urls = %W[http://localhost:3000/1
同期処理的に書ける http://localhost:3000/2 ]
urls.each do |url|
(Ruby の場合は) puts "#{url} #{open(url).read}"
自動的にIO 多重化を end
いいかんじにできる
(Ruby の場合)たいてい、
マルチスレッドで十分! require 'open-uri'
マルチスレッドの短所
urls = %W[http://localhost:3000/1
スレッド特有の多々の問題 http://localhost:3000/2]
排他制御 threads = urls.map do |url|
Thread.start(url) do |url|
デッドロック body = open(url).read
たまに起きる不可解なバグ puts "#{uri} #{body}"
スレッド切り替えが遅い end
end
コンテキスト切替が必要
いつ何が動作している不明 threads.each{|t| t.join}
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 6.
IO多重化 による同時並行処理 5
IO多重化の長所 AsyncHTTPClient の作成
動きがすばやい 巡回したい URL と、
読み込み後にしたい処理
スレッド特有の各種問題に (コールバック)を登録
悩まされない
HTTP 取得処理を実行
IO多重化の短所 取得終了後、登録していた
慣れるまで書きにくい コールバックを呼び出し
逐次的に処理を書けない
慣れが必要
sockets = ソケット作成処理(urls)
状態遷移を管理したり、
loop do
コールバックの登録が readables, = IO.select sockets
常套手段 readables.each do |s|
select(2) を使うプログラム バッファ = s.read_nonblock 65536
sockets.delete s if s.eof?
を書くのは結構大変 end
⇒ そういうときには end
eventmachine break if sockets.empty?
end
登録していたコールバック呼び出し
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 7.
これからの説明 6
eventmachine em-http-request
eventmachine
標準の HTTP による
とは
クライアント HTTPクライアント
Fiber を使った em-synchrony
Fiber とは 非同期処理の を使った
逐次的記述 逐次的記述
EM::Iterator の EM::Synchrony::
コールバックによ Iteratorによる その他 落穂拾い
る記述 逐次的記述
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 8.
eventmachine とは 7
非常に有名なノンブロッキングIO を実現するライブラリ
Heroku 、 Github、 EngineYard などで利用されている
広範なプロトコルに対応
HTTP、SMTP、MySQL 、PostgreSQL、Memcached、Redis
内部的には select(2) による IO 多重化を実現
環境次第では、epoll 、kqueue なども利用可能
非常にスケーラブルな IO 多重化が可能
読み込み処理終了などの”イベント”に対応した処理を記述
返り値は使わず、コールバックを登録する
コールバックの中は、処理完了後に実行される
ret1 = 処理1(引数) 処理1(引数) do |ret|
ret2 = 処理2(ret1) 処理2(ret1) do |ret2|
その後の処理 その後の処理
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 9.
サーバーサイドのスクリプト 8
sinatra/async require 'rubygems'
require 'sinatra'
WEBフレームワーク require 'sinatra/base'
Sinatra の非同期 版 require 'sinatra/async'
require 'eventmachine'
aget が get の非同期 版
仕様 class Delayed < Sinatra::Base
register Sinatra::Async
/1 と /2 に応答を返す
aget "/1" do
ランダムな秒数待つ waitsec = rand * 2
“1” や “2” を返す EM.add_timer waitsec do
body {"1"}
end
end
aget "/2" do
waitsec = rand * 2
EM.add_timer waitsec do
body {"2"}
end
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 10.
EventMachine 標準のHTTPClient 9
require 'rubygems'
ライブラリが数多くの require 'eventmachine'
機能を提供 require 'uri'
イベントループ urls = %W[http://localhost:3000/1
http://localhost:3000/2]
HTTPプロトコル pending = urls.length
コールバック呼出し処理 EventMachine.run do
Client = EM::Protocols::HttpClient
client.callback : urls.each do |url|
正常取得時の処理を登録 uri = URI(url)
client = Client.request(
EM.stop_event_loop :host => uri.host,
:port => uri.port,
イベントループを終了 :request => uri.path,
EM標準の HTTPClient )
はちょっと貧弱 client.callback do |response|
content = response[:content]
リダイレクトに非対応 puts "#{url} content"
プロキシや basic認証に pending -= 1
も非対応 EM.stop_event_loop if pending == 0
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
end
- 11.
em-http-request 10
EventMachine 用の require 'rubygems'
require 'eventmachine'
非同期HTTPライブラリ require 'em-http-request'
高機能 urls = %W[http://localhost:3000/1
リダイレクトに追従 http://localhost:3000/2]
pending = urls.length
Basic 認証に対応 EventMachine.run do
プロキシ、Sock5に対応 Request = EM::HttpRequest
urls.each do |url|
他にもいろいろ client = Request.new(url).get
使い方はほぼ同じ client.callback do
コールバックに終了後の response = client.response
処理を登録 puts "#{url} #{response}"
pending -= 1
EM.stop_event_loop if pending == 0
end
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 12.
Fiber とは 11
Fiber とは f1 = Fiber.new do |i|
puts i #=> 1
軽量スレッド(coroutine) Fiber.yield 2
明示的にスレッドに移ったり、 5
スレッドから戻ったり end
Fiber.yield arg f2 = Fiber.new do |i|
puts 3 #=> 3
現在のファイバーの処理を中断 j = Fiber.yield 4
親ファイバーにもどる puts j #=> 6
7
Fiber#resume の引数が end
Fiber.yield の返り値
(表示) i = f1.resume 1
Fiber#resume arg 1 puts i #=> 2
そのファイバー(self) の 2 j = f2.resume i + 1
3 puts j #=> 4
中断していた場所から再開 4 i = f1.resume
Fiber.yield の引数が 5 puts i #=> 5
Fiber#resume の返り値 6 j = f2.resume 6
7 puts j #=> 7
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 13.
em-http-request の Fiberによる逐次的記述 12
httpget メソッド内 require
require
'rubygems'
'eventmachine'
で、Fiber を利用 require
require
'em-http-request'
'fiber'
EM.run の中は上から順に urls = %W[http://localhost:3000/1
処理を記述 http://localhost:3000/2]
def httpget url
コールバックがない! f = Fiber.current
client = EM::HttpRequest.new(url).get
逐次的に記述できている! client.callback do
いくつか問題が・・・
f.resume client
end
return Fiber.yield
並列処理が行われない end
1個 取得してから pending = urls.size
次の処理を実施する EM.run do
Fiber.new do
自分で Fiber の処理を記述 urls.each do |url|
client = httpget url
汎用的処理なので、 puts "#{url} #{client.response}"
ライブラリに切り出したい
pending -= 1
EM.stop_event_loop if pending == 0
end
end.resume
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 14.
em-synchrony (1) 13
em-synchrony を使うと require
require
'rubygems'
'eventmachine'
EM.synchrony メソッドを require 'em-http-request'
require 'em-synchrony'
利用可能になる require 'em-synchrony/em-http'
get メソッドが内部的に
urls = %W[http://localhost:3000/1
Fiber を用いるメソッドに http://localhost:3000/2]
置き換わる
EM.synchrony do
同期的な記述でノンブロッキ urls.each do |url|
ング処理を実現できる request = EM::HttpRequest.new(url)
res = request.get.response
けど、まだ同時並行処理 puts "#{url} #{res}"
end
は行われない EM.stop_event_loop
end
1個ずつURLを取得する
(涙)
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 15.
em-synchrony (2) 14
複数の URL からの取得を require
require
'rubygems'
'eventmachine'
同時並行で行うには require 'em-http-request'
require 'em-synchrony'
それぞれの URL からの取得 require 'em-synchrony/em-http'
処理を Fiber で囲む
urls = %W[http://localhost:3000/1
それぞれの取得処理が同時に http://localhost:3000/2]
実行される pending = urls.length
求めるものが得られた! EM.synchrony do
urls.each do |url|
できれば、1000個の URL を Fiber.new do
request = EM::HttpRequest.new(url)
5個づつ並行に処理したり response = request.get.response
したいんだけど・・・ puts "#{url} #{response}"
pending -= 1
EM.stop_event_loop if pending == 0
end.resume
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 16.
EM::Iterator のコールバックによる記述 15
EM::Iterator require 'rubygems'
require 'eventmachine'
EventMachine 用の require 'em-http-request'
イテレータ
urls = %W[http://localhost:3000/1
each、map、inject http://localhost:3000/2]
iter.next で
後続の要素を処理 concurrency = 2
pending = urls.length
iter.return で EventMachine.run do
値を返す EM::Iterator.new(urls, concurrency).each
do |url, iter|
new の第2引数で client = EM::HTTPRequest.new(url).get
同時実行数を指定可能 client.callback do
response = client.response
puts "#{url} #{response}"
pending -= 1
EM.stop_event_loop if pending == 0
iter.next
end
end
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 17.
EM::Synchrony::Iterator 16
EM::Synchrony::Iterator require
require
'rubygems'
'eventmachine'
Fiber を使って、each 以降 require 'em-http-request'
require 'em-synchrony'
の処理を、すべての要素の require 'em-synchrony/em-http'
処理終了後に実行するもの
urls = %W[http://localhost:3000/1
Fiber で囲むのを http://localhost:3000/2]
なくせると思っていたら
concurrency = 2
そういうものではなかった。 EventMachine.synchrony do
残りの処理数を管理する EM::Synchrony::Iterator.new(urls,
concurrency).each do |url, iter|
変数 pending が不要 Fiber.new do
client = EM::HttpRequest.new(url)
response = client.get.response
puts "#{url} #{response}"
iter.next
end.resume
end
EM.stop_event_loop
end
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 18.
落穂拾い(1) em-synchrony の他の機能 17
複数の主要プロトコルへの対応
redis、mysql、mongodb、memcached
自分で新たなプロトコルに対応するのも容易
EM::Synchrony::Multi
すべての要素が終了したときに処理を実行するときに使う
EM::Synchrony::ConnectionPool
MySQL などのコネクションプーリングで利用可能
EM::Synchrony::TCPSocket
TCPSocket クラスをその気になれば代替できるクラス
setsockopt などいくつかのメソッドが非互換
EM::Synchrony::Thread::ConditionVariable
リソースの取得待ちなどが簡単に実現可能
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 19.
落ち穂拾い(2) いろいろ困ったこと 18
Ruby 1.9 が利用可能な環境の構築
Cygwin ではコンパイルできない
VMWare で一度チャレンジして途中で挫折
理由わすれた
VirtualBox で再度トライしてうまくいった
VitualBox は VMWare よりずっと使いやすくて便利!
Windows プログラムの利用がなければ Cygwin よりいいかも。
em-http-request のインストール
「gem install --pre em-http-request」とすることが必要
--pre をつけると、1.0.0.beta4 がインストールされる
つけないと、0.3.0 がインストールされる
em-http-request 1.0 系列でないと em-synchrony が使えない
em-http-request は 0.3 と 1.0 で非互換な部分が多い
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 20.
まとめ 19
スレッドと IO 多重化の2方式で同時並行処理を比較
(Ruby の場合は)たいていスレッドで十分
スレッド特有のバグ、速度が遅すぎるなどの課題があれば、
IO多重化(event machine など)の利用を検討
Event Machine
ノンブロッキングIO を実現するライブラリ
単一イベントループとコールバックによる対応処理の記述
em-synchrony
逐次的記述でノンブロッキングな処理が実現可能
内部実装に、Fiber を利用
複数の URL からの同時取得処理もかんたん
コネクションプール
Ruby/Rails勉強会@関西 第50回 「em-synchrony について」
- 21.