あーるPG - 社会人のデジタル生活

日曜プログラマになろうかなーと思った30代理系社会人の、キャリアアップや趣味(特にデジタル情報)の記録。らーめんとビールが好き。

明示的なGC

file = "hoge.txt"
open("tempfile", "wb").write open(file).read
open("tempfile", "rb").each{|line|
    p line
}

2行目で書いたファイルを3行目で読もうとするが、出力されるのは途中まで。何故か。
IOは非同期*1で読み書きしており、closeされるか明示的にflush*2などしない限り完了が保証されないらしい。Rubyでは”変数で参照されなくなったfd*3GC*4によりcloseされる”となっているが、fdが参照されなくなった時点でGCされるわけではない。つまり上記の書き方ではいつ終わるかわからない。ただ、3行目のようにブロック文があるときはブロック終了時にcloseされる。
解決策はいろいろある。明示的にIO#close*5する、IO#fsyncする、IO#sync=trueするなど。以下のように明示的にGCする方法もある。GC#startがあるのにGC#waitが無いのはきっと終了まで待つからだろう。

file = "hoge.txt"
open("tempfile", "wb").write open(file).read
GC.start
open("tempfile", "rb").each{|line|
    p line
}

*1:一応書いておくけど、たとえばファイルを書くとき、次の命令を処理するときに書き込みが完了しているのが同期IO、完了せずとも次の処理をしてしまうのが非同期IO。

*2:一応書いておくけど、IO用バッファを空にして、IOを完了させること

*3:ファイルディスクリプタ。ファイルハンドルの方が合ってるかも

*4:ガーベジコレクタ

*5:Rubyの場合CクラスのメンバMはC#Mと書くらしい