- 締切済み
$| = 42; って?
既存ロジックを解析しています。 LOG出力のとき、 $LOGFILE = "$LOGFILEPATH/$LOGFILE"; if (! open(LOG, "> $LOGFILE")) { print "Error - ログファイルのオープンに失敗しました\n"; print " [$LOGFILE]\n"; exit(0); } $| = 42; select(LOG); $| = 42; select(STDOUT); とあり、$| = 42;がわからず調べ始めたら $| に0以外を入れるとバッファリングしない、とありました。他のHPでバッファリングしたほうが効率がいい、とあり、 バッファリングの意味も大体理解したつもりなのですが、 どうして効率が悪くなるはずの上記のようなロジックが あるのかわかりません。 よろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
>バッファリングを有効にしているとバッファ蓄積中にプログラムが落ちてしまい、 >蓄積されたログデータが出力されない 基本的に、そのような理解が正解に近いのですが、 実際はそうではありません。 ユーザスクリプトがコケるとき、perlインタプリタは後始末をします。 それゆえ、バッファが吐き出され、ログデータが出力されるかと思います。 perlインタプリタ自体が、コケるような致命的な状況については バッファは保証されません。(たぶん) なので、そのようなケースを意識して、バッファリングしないのかも知れませんが.. 何を意図して、そうしたかは、ソースの断片からでは判断できません。
- Tacosan
- ベストアンサー率23% (3656/15482)
#3 です. バッファリングする/しないというのはファイルハンドルごとに決まっています. だから, $| = 1; select(LOG); とやると, 次に select(LOG); するまでは LOG に対する出力はバッファリングされないままとなります.
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
>どうして効率が悪くなるはずの上記のようなロジックが >あるのかわかりません。 投稿されたソースの断片で、バッファリングをしない意義を判断することは出来ませんが.. バッファリングしている場合、フラッシュ(書き込み)のタイミングは、バッファが埋まるか、 クローズのタイミングであり、プログラムの進行と非同期にフラッシュされます。 一般的に、進行状況表示やタイプイン要求のように、意図したタイミングで出力したい時に それが出来ません。 なので、場合によっては、処理効率を犠牲にしてでも、バッファリングをしないケースもあり、 それはそれで、無意味なわけではありません。
- Tacosan
- ベストアンサー率23% (3656/15482)
確か $| によるバッファリングの制御はそのあとで select しないといけなかったはずです. つまり, LOG というファイルハンドルのバッファリングを無効にするには $| = 1; select LOG; としなければなりません. で, このままだと print がデフォルトで使うファイルハンドルも LOG になってしまうので select STDOUT; が必要なのですが, $| が 1 のままだと select したときに STDOUT のバッファリングも無効になってしまいます. よって, さらに $| = 0; select STDOUT; も必要となります.
お礼
いつも回答ありがとうございます。 少し疑問が湧いたのでまたお付き合いください。 上記文章の意味ですが、つまり $| = 1; select LOG; とすると普通のPRINT文で出力されるバッファも無効になるので $| = 0; select STDOUT; が必要と理解しました。そうしたときLOGに対するバッファリング無効は戻らない、ということになりますか? また、そうだとするとLOGに対しては無効、STDOUTに関しては有効、ということになりますか?
実数に意味はないです。 「0以外を入れると」と決められてるんですから、「0かそれ以外か」の意味しかないです。 ゆえに、 $|=42; というコマンドを何度も実行しているのは無駄です。前後の処理が分からないんでなんともいえませんが、多分2度目のは $|=0; の間違いです。 (もしそうだとしたら、そこで戻してどーするというツッコミが来てしまいますが(^_^;) select(LOG); というのは、ようするに出力をログに流すためのものです。 通常は、print LOG "wwwww"; と書かなければならないところを、print "wwwww"; と書くだけでファイル出力されるようにするんです。
お礼
なるほど。確かにprint LOG と書くのは結構手間ですよね。よくわかりました。ありがとうございました。
バッファリングとかすると、書き込み遅延が発生したりするからです。 それを防ぐための保険的ロジックとして、わざと入れることがあるんです。
お礼
早速の回答ありがとうございます。 つまり、一度やってみてログ出力のせいで、もしくは、プログラムが遅かったので少しでも早くするために入れた、と認識してよろしいでしょうか? また$|の値には42か43が代入されているのですが、それに 意味はありますか? あと、select(LOG)の記述もよかったら解説していただけませんでしょうか?
お礼
回答ありがとうございました。 上記の解釈ですが、たとえば、バッファリングを無効にしておくと、途中でプログラムが落ちた場合、確実にそこまでのログははかれているが、バッファリングを有効にしているとバッファ蓄積中にプログラムが落ちてしまい、蓄積されたログデータが出力されない、ようなイメージなのでしょうか?