SlideShare a Scribd company logo
1 of 20
IOクラスの入出力メソッドについて cuzic 2010/04/24 第42回 Ruby/Rails 勉強会@関西
自己紹介 cuzic 「きゅーじっく」と読みます。 ×quzic × cusic 「リファクタリング Ruby エディション」 の読書会を計画しています。 @ JR 尼崎駅徒歩2分(小田公民館) 日程未定 Kent Beck 著  最近 JavaScriptの勉強中 関数が First-Class Object でいいね。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
IO クラス みんな知っているよね? puts “Hello, World!” STDOUT や STDIN は IO のインスタンス open(“/tmp/tempfile”) do |io| ~end ファイル入出力だけでなく、ネットワーク処理などにも IO クラスを利用。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
Ruby のIO はかしこい Ruby のスレッドとうまく連携 ブロックする IO#read/IO#writeは内部的にselect(2) を利用。上手に他のスレッドを実行 高水準 IO と低水準  IO の両方が利用可能 高水準IO : FILE構造体(stdio)を使う printf(3) や puts(3)  低水準IO : file descriptor を使う read(2) など エラーが生じると例外を raise。 EAGAIN、EINTR、EWOULDBLOCK とか 低レベルのシステムコールも数多く利用可能 fcntl (2) 、fsync (2) などに加え、BasicSocketではgetsockopt(2) や recv(2) なども利用可能 2010/04/24 第42回 Ruby/Rails 勉強会@関西
IO#read (1) IO#readlength 長さを指定したいときはふつう これを使う。 buffer = nil open(“/dev/urandom”) do |io|  buffer = io.read 10 end p buffer #=> "16X220017uT3632t" 2010/04/24 第42回 Ruby/Rails 勉強会@関西
IO#read (2) IO#readlength, buffer 実は 第二引数を指定可能。事前にメモリ割り当てすることで高速化。 require ‘benchmark’ buffer = “ “ * 1000 Benchmark.measure do    open(“/dev/zero”) do |io| 1000_000.times do        io.read 1000, buffer    end   endend.display #=>  1.5000   0.0000   1.5000 (  1.3980) (比較) 58.8900   4.3440  63.2340 ( 62.6950) 2010/04/24 第42回 Ruby/Rails 勉強会@関西
IO#sysread IO#sysreadは IO#readとどう違うの? IO#read は 受信バッファ を経由する IO#sysreadは 受信バッファ を経由しない 受信バッファ って? IO はファイル以外にもいろいろ扱う ネットワーク( TCP/UDP 等)とか 欲しい length のデータがそろうまで、内部的にデータを貯めておいたり 取り出されるのに先立って、データを保存しておいたり 2010/04/24 第42回 Ruby/Rails 勉強会@関西
受信バッファ ,[object Object]
反面、ブロック(待ち)が発生してしまう。高速化の障壁になることも・・・。・待たずに別の処理をしたいのに・・・。・ある分だけでいいからすぐ欲しいのに・・・。2,000 Byte 欲しいなぁ。。。 受信バッファ ( 1,500Byte) パケット1000Byte パケット1000Byte まだないから、ちょっと待っとこっと。(ブロックの発生)
IO#readと IO#sysread IO#readを使うと欲しい長さだけ取得可能IO#sysreadを使うと待ちが生じない r, w = IO.pipe str = "0123456789" Thread.startdo w.writestr   sleep 10 w.writestr end puts Time.now.strftime("%H:%M:%S") buffer = r.read 15 # ここで、ブロック(待ちが発生)する puts Time.now.strftime("%H:%M:%S") puts buffer #=> “012345678901234” r, w = IO.pipe str = "0123456789" Thread.startdo w.writestr   sleep 10 w.writestr end puts Time.now.strftime("%H:%M:%S") buffer = r.sysread 15# すぐに次の行に移る puts Time.now.strftime("%H:%M:%S") puts buffer #=> “0123456789”
混ぜるな危険 待ちをできるかぎり少なくしたいけど、、、 IO#readと IO#sysreadは同時利用不可 受信バッファの都合で、同時に使うとバグの元 IO#gets、IO#each_lineなど、みんな IO#sysreadとは同時利用できません・・・。 けど、どうしても同時に使いたい!!! そんなあなたに耳よりな話があります!! IO#read_nonblock IO#readpartial 2010/04/24 第42回 Ruby/Rails 勉強会@関西
IO#readpartial Ruby 1.8.3 以降で利用可能 受信バッファにデータがある場合は、とりにいかない
IO#readpartial IO#readpartialでは受信バッファに貯めることはしない
IO#read_nonblock Ruby 1.8.5 以降で利用可能 IO#readpartialと同様に IO#read等との同時利用が可能 取り出せるものが何もないときは、例外が発生する 何か取り出せるものがあれば、それを返す
各メソッドの動作 IO#read (ブロッキングモード) 確実にlength のデータを返す 足りてなかったら、データの到着を待つ IO#readpartial 求める length のデータがそろってなくても、ある分だけ返す 返すべきデータが何もなければブロックする。 けど、なんかデータが到着したら、それを返す。 IO#read_nonblock 返すべきデータがなければ例外を raise する。ブロックしない。 IO#sysread (ノンブロッキングモード) IO#read等と混用できない点を除いて、IO#read_nonblockと同じ動作 どの Ruby でも問題なく動く。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
細かい違いを整理する
いつ使うの? IO#readpartiallength 取り出せるものが何かあれば取り出したいが、何もなければ、ブロックして欲しいとき length を大きな値として、ネットワークプログラミングなどで利用したり。 IO#sysreadと違い、IO#read等と共存可能 IO#read_nonblocklength 一切ブロックさせずに IO を利用したい場合 IO#sysreadと違い、IO#read等と共存可能 IO#sysreadlength 文字数がずっと短い IO#sysread使いこそが真の漢(?)。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
具体的な利用例は? Mongrel Ruby で書かれた Web サーバ 一部で readpartialを利用している SecureRandom Ruby 1.8.7 以降標準添付 安全な乱数生成機 /dev/urandomを readpartialで読み込み※ Unix 環境の場合 EventMachine 非同期サーバを作るフレームワーク 一部で read_nonblockを利用している 2010/04/24 第42回 Ruby/Rails 勉強会@関西
まとめ 「リファクタリング Ruby エディション」読書会を計画中 Ruby の IO はかしこい 低水準のことも高水準のこともできちゃう IO#readの第2引数は高速化に役立つ こともある。 IO#readpartialはネットワークプログラミングなどで重宝する
ご静聴ありがとうございました。

More Related Content

What's hot

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
react-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのかreact-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのか暁 三宅
 
20160526 依存関係逆転の原則
20160526 依存関係逆転の原則20160526 依存関係逆転の原則
20160526 依存関係逆転の原則bonjin6770 Kurosawa
 
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!Masahito Zembutsu
 
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 ( Redmine of one plant 2022 ...
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 (  Redmine of one plant 2022 ...ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 (  Redmine of one plant 2022 ...
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 ( Redmine of one plant 2022 ...Kohei Nakamura
 
Linux-HA Japanプロジェクトのこれまでとこれから
Linux-HA JapanプロジェクトのこれまでとこれからLinux-HA Japanプロジェクトのこれまでとこれから
Linux-HA Japanプロジェクトのこれまでとこれからksk_ha
 
マイクロサービスにおける 非同期アーキテクチャ
マイクロサービスにおける非同期アーキテクチャマイクロサービスにおける非同期アーキテクチャ
マイクロサービスにおける 非同期アーキテクチャota42y
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計Kouji YAMADA
 
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)NTT DATA Technology & Innovation
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMPYusuke Kagata
 
テストとリファクタリングに関する深い方法論 #wewlc_jp
テストとリファクタリングに関する深い方法論 #wewlc_jpテストとリファクタリングに関する深い方法論 #wewlc_jp
テストとリファクタリングに関する深い方法論 #wewlc_jpkyon mm
 
Dockerを支える技術
Dockerを支える技術Dockerを支える技術
Dockerを支える技術Etsuji Nakai
 
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までDocker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までMasahito Zembutsu
 
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?naoki koyama
 
どうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIどうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIKoichiro Sumi
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法についてYuji Otani
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことyoku0825
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説murachue
 

What's hot (20)

SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
react-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのかreact-scriptsはwebpackで何をしているのか
react-scriptsはwebpackで何をしているのか
 
KafkaとPulsar
KafkaとPulsarKafkaとPulsar
KafkaとPulsar
 
20160526 依存関係逆転の原則
20160526 依存関係逆転の原則20160526 依存関係逆転の原則
20160526 依存関係逆転の原則
 
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!Dockerライフサイクルの基礎 地雷を踏み抜けろ!
Dockerライフサイクルの基礎 地雷を踏み抜けろ!
 
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 ( Redmine of one plant 2022 ...
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 (  Redmine of one plant 2022 ...ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 (  Redmine of one plant 2022 ...
ある工場の Redmine 2022 〜ある工場の Redmine 5.0 バージョンアップ〜 ( Redmine of one plant 2022 ...
 
Linux-HA Japanプロジェクトのこれまでとこれから
Linux-HA JapanプロジェクトのこれまでとこれからLinux-HA Japanプロジェクトのこれまでとこれから
Linux-HA Japanプロジェクトのこれまでとこれから
 
マイクロサービスにおける 非同期アーキテクチャ
マイクロサービスにおける非同期アーキテクチャマイクロサービスにおける非同期アーキテクチャ
マイクロサービスにおける 非同期アーキテクチャ
 
クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計クラウド環境下におけるAPIリトライ設計
クラウド環境下におけるAPIリトライ設計
 
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
乗っ取れコンテナ!!開発者から見たコンテナセキュリティの考え方(CloudNative Days Tokyo 2021 発表資料)
 
テストコードの DRY と DAMP
テストコードの DRY と DAMPテストコードの DRY と DAMP
テストコードの DRY と DAMP
 
テストとリファクタリングに関する深い方法論 #wewlc_jp
テストとリファクタリングに関する深い方法論 #wewlc_jpテストとリファクタリングに関する深い方法論 #wewlc_jp
テストとリファクタリングに関する深い方法論 #wewlc_jp
 
Dockerを支える技術
Dockerを支える技術Dockerを支える技術
Dockerを支える技術
 
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応までDocker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
Docker Compose入門~今日から始めるComposeの初歩からswarm mode対応まで
 
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
新たなgitのブランチモデル「Git Feature Flow」!Git Flow,Git Hub Flow,Git Lab Flowを超えれるか?
 
どうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCIどうやらテスト駆動型開発は死んだようです。これからのCI
どうやらテスト駆動型開発は死んだようです。これからのCI
 
Redisの特徴と活用方法について
Redisの特徴と活用方法についてRedisの特徴と活用方法について
Redisの特徴と活用方法について
 
MySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいことMySQL 5.7にやられないためにおぼえておいてほしいこと
MySQL 5.7にやられないためにおぼえておいてほしいこと
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
Yahoo! JAPANにおけるApache Cassandraへの取り組み
Yahoo! JAPANにおけるApache Cassandraへの取り組みYahoo! JAPANにおけるApache Cassandraへの取り組み
Yahoo! JAPANにおけるApache Cassandraへの取り組み
 

More from Tomoya Kawanishi

ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例Tomoya Kawanishi
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウTomoya Kawanishi
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列についてTomoya Kawanishi
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてTomoya Kawanishi
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されることTomoya Kawanishi
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler についてTomoya Kawanishi
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現についてTomoya Kawanishi
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行についてTomoya Kawanishi
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについてTomoya Kawanishi
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことTomoya Kawanishi
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選Tomoya Kawanishi
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと WebクローリングについてTomoya Kawanishi
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interfaceTomoya Kawanishi
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能についてTomoya Kawanishi
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーTomoya Kawanishi
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO についてTomoya Kawanishi
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介Tomoya Kawanishi
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてTomoya Kawanishi
 

More from Tomoya Kawanishi (20)

英単語の覚え方
英単語の覚え方英単語の覚え方
英単語の覚え方
 
ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウ
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列について
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構について
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されること
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler について
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現について
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行について
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについて
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったこと
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと Webクローリングについて
 
Rake
RakeRake
Rake
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interface
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能について
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO について
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについて
 

Ruby 勉強会 第42回 発表資料 IO について

  • 2. 自己紹介 cuzic 「きゅーじっく」と読みます。 ×quzic × cusic 「リファクタリング Ruby エディション」 の読書会を計画しています。 @ JR 尼崎駅徒歩2分(小田公民館) 日程未定 Kent Beck 著 最近 JavaScriptの勉強中 関数が First-Class Object でいいね。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 3. IO クラス みんな知っているよね? puts “Hello, World!” STDOUT や STDIN は IO のインスタンス open(“/tmp/tempfile”) do |io| ~end ファイル入出力だけでなく、ネットワーク処理などにも IO クラスを利用。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 4. Ruby のIO はかしこい Ruby のスレッドとうまく連携 ブロックする IO#read/IO#writeは内部的にselect(2) を利用。上手に他のスレッドを実行 高水準 IO と低水準 IO の両方が利用可能 高水準IO : FILE構造体(stdio)を使う printf(3) や puts(3) 低水準IO : file descriptor を使う read(2) など エラーが生じると例外を raise。 EAGAIN、EINTR、EWOULDBLOCK とか 低レベルのシステムコールも数多く利用可能 fcntl (2) 、fsync (2) などに加え、BasicSocketではgetsockopt(2) や recv(2) なども利用可能 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 5. IO#read (1) IO#readlength 長さを指定したいときはふつう これを使う。 buffer = nil open(“/dev/urandom”) do |io| buffer = io.read 10 end p buffer #=> "16X220017uT3632t" 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 6. IO#read (2) IO#readlength, buffer 実は 第二引数を指定可能。事前にメモリ割り当てすることで高速化。 require ‘benchmark’ buffer = “ “ * 1000 Benchmark.measure do open(“/dev/zero”) do |io| 1000_000.times do io.read 1000, buffer end endend.display #=> 1.5000 0.0000 1.5000 ( 1.3980) (比較) 58.8900 4.3440 63.2340 ( 62.6950) 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 7. IO#sysread IO#sysreadは IO#readとどう違うの? IO#read は 受信バッファ を経由する IO#sysreadは 受信バッファ を経由しない 受信バッファ って? IO はファイル以外にもいろいろ扱う ネットワーク( TCP/UDP 等)とか 欲しい length のデータがそろうまで、内部的にデータを貯めておいたり 取り出されるのに先立って、データを保存しておいたり 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 8.
  • 10. IO#readと IO#sysread IO#readを使うと欲しい長さだけ取得可能IO#sysreadを使うと待ちが生じない r, w = IO.pipe str = "0123456789" Thread.startdo w.writestr sleep 10 w.writestr end puts Time.now.strftime("%H:%M:%S") buffer = r.read 15 # ここで、ブロック(待ちが発生)する puts Time.now.strftime("%H:%M:%S") puts buffer #=> “012345678901234” r, w = IO.pipe str = "0123456789" Thread.startdo w.writestr sleep 10 w.writestr end puts Time.now.strftime("%H:%M:%S") buffer = r.sysread 15# すぐに次の行に移る puts Time.now.strftime("%H:%M:%S") puts buffer #=> “0123456789”
  • 11. 混ぜるな危険 待ちをできるかぎり少なくしたいけど、、、 IO#readと IO#sysreadは同時利用不可 受信バッファの都合で、同時に使うとバグの元 IO#gets、IO#each_lineなど、みんな IO#sysreadとは同時利用できません・・・。 けど、どうしても同時に使いたい!!! そんなあなたに耳よりな話があります!! IO#read_nonblock IO#readpartial 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 12. IO#readpartial Ruby 1.8.3 以降で利用可能 受信バッファにデータがある場合は、とりにいかない
  • 14. IO#read_nonblock Ruby 1.8.5 以降で利用可能 IO#readpartialと同様に IO#read等との同時利用が可能 取り出せるものが何もないときは、例外が発生する 何か取り出せるものがあれば、それを返す
  • 15. 各メソッドの動作 IO#read (ブロッキングモード) 確実にlength のデータを返す 足りてなかったら、データの到着を待つ IO#readpartial 求める length のデータがそろってなくても、ある分だけ返す 返すべきデータが何もなければブロックする。 けど、なんかデータが到着したら、それを返す。 IO#read_nonblock 返すべきデータがなければ例外を raise する。ブロックしない。 IO#sysread (ノンブロッキングモード) IO#read等と混用できない点を除いて、IO#read_nonblockと同じ動作 どの Ruby でも問題なく動く。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 17. いつ使うの? IO#readpartiallength 取り出せるものが何かあれば取り出したいが、何もなければ、ブロックして欲しいとき length を大きな値として、ネットワークプログラミングなどで利用したり。 IO#sysreadと違い、IO#read等と共存可能 IO#read_nonblocklength 一切ブロックさせずに IO を利用したい場合 IO#sysreadと違い、IO#read等と共存可能 IO#sysreadlength 文字数がずっと短い IO#sysread使いこそが真の漢(?)。 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 18. 具体的な利用例は? Mongrel Ruby で書かれた Web サーバ 一部で readpartialを利用している SecureRandom Ruby 1.8.7 以降標準添付 安全な乱数生成機 /dev/urandomを readpartialで読み込み※ Unix 環境の場合 EventMachine 非同期サーバを作るフレームワーク 一部で read_nonblockを利用している 2010/04/24 第42回 Ruby/Rails 勉強会@関西
  • 19. まとめ 「リファクタリング Ruby エディション」読書会を計画中 Ruby の IO はかしこい 低水準のことも高水準のこともできちゃう IO#readの第2引数は高速化に役立つ こともある。 IO#readpartialはネットワークプログラミングなどで重宝する
  • 21. おまけ( io/nonblock) Ruby 1.8 / 1.9 には io/nonblockというノンブロッキングモードにするライブラリがあるが・・・ 正直、私にはよく分かりません・・・。 期待した動作をしないし、、、 昔のバージョンでは効果があった??? Cygwin にはない??? open の第2引数は効果があるみたいopen(“/tmp/fifo”, IO::NONBLOCK | IO::RDONLY)