2016-08-16 17 views
0

の実行/ /デッドロック飢餓状態に私は、ファイルシステム内の重複ファイルのレポートを作成するためにduffを使用している:私はにこのレポートを変換するために、いくつかのグルーヴィーなスクリプトを書かれているバッシュパイプラインシェルスクリプトは不十分

duff ~/Photos > ~/Photos/duplicates.txt 

約50%の時間で、問題なく美しく動作します。

私のスクリプトの中には、実行を開始しないものや、非常に遅いものがあります。これはなぜですか、それを防ぐために私は何ができますか? (そしてなぜgrepのような「専門的に書かれた」コマンドラインプログラムはこの問題に悩まされない?)

詳しい情報

  • しばらく それは(STD入力を受け取るまで、私は、各スクリプトの開始を遅らせますデータなし、2.5秒間スリープ)。スリープ間隔が
  • 私は一緒に接続してより多くのパイプが、より頻繁にそれが起こる短かったとき飢餓はここだ
  • (私はちょうどcat後、私のいずれかのスクリプトを実行する場合、私は問題を取得することはありません、) より頻繁でした私のスクリプトのそれぞれを使用しているテンプレート(私はGroovyのランタイムを使用しますが、プレーンなJava構文に固執する):

    のpublic static無効メイン(文字列[] args)をスロー{

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    
    while (!br.ready()) { 
        Thread.sleep(2500L); 
    } 
    
    while (br.ready()) { 
        String inputLine = br.readLine(); 
        // Do stuff 
    } 
    

    }

    IOExceptionが

答えて

2

ストリームが準備完了しているかどうかチェックするのはなぜですか?あなたがしたいのは、データが利用可能になるのを待って、利用可能なときにそれを読むことです。通常の潜在的にブロックされている読み込みを使用するだけであれば、それが起こります。

コードを抜粋したデータがすぐに利用できなくなるとすぐに読み取りループを終了すると、プログラムは少なくとも時間の早い段階で終了する可能性があります。あなたがEOFを見るまで、読んだだけで(おそらくデータが利用可能になるまでブロックするかもしれません)、物事はちょうどうまくいくはずです。 (これはgrepや他の "専門的に書かれたプログラム"が行うことです)

+0

ああ、私は '.ready()'がEOFを見るまで読み込みと同等であると思っていました。私はこれを試してみましょう。 (私はあなたがループ条件の中でループ変数に割り当てる恐ろしいイディオムを避けようとしていました)。 –

+0

'ready'への呼び出しがEOFチェックと同等であれば、2.5秒後に再テストするのはちょっとばかげているでしょうか?パイプは、利用可能なデータがないため、EOFを返しません。 (最後の)ライターがファイル記述子を閉じるときにEOFを返します。 – rici

+0

私はあなたが今述べた常識的な側面を熟考しなければならないでしょう。しかしそれまでは、私はこれがうまくいくと言うことができてうれしいです:)ありがとう。 –

2

あなたが提供した情報が限られている理由は言うまでもありません。 groovyの別のインスタンスにパイプするたびに、新しいjvmを起動しています。オーバーヘッドがあり、それがシステムに課税されます。 (Javaのデフォルトの起動設定を確認してください)

もう一つは、あなたのスクリプトは2.5秒間スリープしてから仕事に取り掛かり、2.5秒間スリープ状態に戻ります。行うには、他のスクリプトのいずれかを持って仕事がある場合

2.5 + 2.5 + 2.5 = 7.5秒

以上:など、寝ている、他の出力を待っているあなたは最高のを待つことができます1秒以上(javaで直接Stringを処理するようなもの)... bash、grepなどの使い方を学ぶ価値があるかもしれません。最初にホイールと2番目の再発明を避けるには、正しい仕事。

Groovyは素晴らしいですが、おそらくgrep -vを使ってフィルタをかけることができますし、duffをjsonに、jsonをhtmlに、恐らくurアダプタを直接HTMLに書き込むことができますか?テキストを変換するために何をしているかのような音は、おそらくあまり効率的ではありません...

+0

あなたの考えを共有してくれてありがとう。 Java/groovyをバイパスすることについては、Javaでbashよりも簡単なやり方をしているだけなので、私はむしろそうしたいと思います。また、私は、巨大なエンタープライズJavaアプリケーションが悪いこと、そしてパイプで同じことをもっとモジュラー的に達成できることを自分自身に証明しようとしています。 –

+1

ほとんどのエンタープライズJavaアプリケーションは悪いですが、シェル、パイプ、Groovyスクリプトは必ずしもその問題を解決する最善の方法ではありません。 Googleマイクロサービス – sloven

+0

お読みいただきありがとうございます。それはより実用的です。 –

関連する問題