2

私はopen4宝石を使用していますが、生成されたプロセスの標準出力からの読み取りに問題があります。私はルビープログラムを持っていますtest1.rb:

print 'hi.' # 3 characters
$stdin.read(1) # block

そして、同じディレクトリにある別の ruby​​ プログラムtest2.rb:

require 'open4'

pid, stdin, stdout, stderr = Open4.popen4 'ruby test1.rb'
p stdout.read(2) # 2 characters

2 番目のプログラムを実行すると:

$ ruby test2.rb

何も印刷せずに永遠にそこに座っています。なぜこれが起こるのですか?それを止めるにはどうすればよいですか?

4

3 に答える 3

2

これに変更test1.rbする必要がありました。どうしてか分かりません。

print 'hi.' # 3 characters
$stdout.flush
$stdin.read(1) # block
于 2010-07-15T23:02:03.473 に答える
2

デフォルトでは、printstdout または別のファイルに出力するものはすべて、Ruby のバッファー (または Ruby の下にある標準 C ライブラリー) に書き込まれます。次のいずれかのイベントが発生すると、バッファーの内容が OS に転送されます。

  • バッファがいっぱいになります。
  • stdout を閉じます。
  • 改行シーケンス (`\n') を出力しました
  • flush明示的に呼び出します。

他のファイルについては、 のflushように、他の機会にも行われますftell

標準出力を非バッファ モード ( $stdout.sync = true) にすると、バッファは使用されません。

stderr はデフォルトでバッファリングされません。バッファリングを行う理由は効率です。出力データをバッファに集約すると、多くのシステム コール (オペレーティング システムへのコール) を節約できます。システム コールは非常に高価です。数百または数千もの CPU サイクルが必要です。少しのコードとユーザー空間のいくつかのバッファーでそれらを回避すると、速度が大幅に向上します。

バッファリングに関する良い読み物:改行が書式文字列に含まれていない限り、呼び出し後に printf がフラッシュされないのはなぜですか?

于 2014-10-31T13:09:01.143 に答える
1

私はプロセスの専門家ではありません。

API ドキュメントを初めて見たとき、open4 を使用するシーケンスは次のようになりました。最初にテキストを stdin に送信し、次に stdin を閉じ、最後に stdout からテキストを読み取ります。

そう。あなたはこのtest2.rbようにすることができます

require 'open4'

pid, stdin, stdout, stderr = Open4.popen4 'ruby test1.rb'
stdin.puts "something" # This line is important
stdin.close # It might be optional, open4 might close itself.
p stdout.read(2) # 2 characters
于 2010-07-12T03:10:42.903 に答える