2017-03-02 2 views
1

hereのように、並列ジョブをbashで実行する方法を実装しました。Bashの並行ジョブがスタックする

私は約13000行のファイルをループしています。私はちょうどのような、それぞれのラインをテストし、印刷しています:

#!/bin/bash 
max_bg_procs(){ 
    if [[ $# -eq 0 ]] ; then 
     echo "Usage: max_bg_procs NUM_PROCS. Will wait until the number of background (&)" 
     echo "   bash processes (as determined by 'jobs -pr') falls below NUM_PROCS" 
     return 
    fi 
    local max_number=$((0 + ${1:-0})) 
    while true; do 
     local current_number=$(jobs -pr | wc -l) 
     if [[ $current_number -lt $max_number ]]; then 
       echo "success in if" 
       break 
     fi 
     echo "has to wait" 
     sleep 4 
    done 
} 

download_data(){ 
    echo "link #" $2 "["$1"]" 
} 

mapfile -t myArray < $1 

i=1 
for url in "${myArray[@]}" 
do 
    max_bg_procs 6 
    download_data $url $i & 
    ((i++)) 
done 
echo "finito!" 

私はまた、thisthisなどの他の解決策を試してみたが、私の問題は、永続的である:

「ランダム」は、与えられたステップ通常は2000番目と5000番目の反復の間に、単に詰まってしまいます。私はコードの中にさまざまなものを入れて、どこに行き詰まっているのかを確認しましたが、最後に印刷するのは$url $iです。

私は単純なテストを行って並列性を取り除き、ファイルの内容をループさせました。すべてうまく行き、最後までループしました。

だから、私は並列性にいくつかの制限がないと思うし、誰かがそれを理解するのを手伝ってくれるのだろうかと思う。

多くの感謝!

+2

http://mywiki.wooledge.org/ProcessManagementは、開始するには良い場所です。 –

+0

なぜ、 '' $ 2' ["$ 1"] "' – Inian

+2

の 'echo 'リンクで' $ 1'の周りに余分な二重引用符があるのですか?このコード。ここに投稿する前に、http://shellcheck.net/でスクリプトを実行することを検討してください。 –

答えて

3

ここでは、最大6つのパラレルbashプロセス(download_data)を呼び出しています。これらのプロセスのそれぞれは、呼び出しごとに最大16個のURLが渡されます。自分のチューニングごとに調整します。

bash(エクスポートされた関数のサポート)とGNU xargsの両方が必要であることに注意してください。 GNUを使用

#!/usr/bin/env bash 
#    ^^^^- not /bin/sh 

download_data() { 
    echo "link #$2 [$1]" # TODO: replace this with a job that actually takes some time 
} 
export -f download_data 
<input.txt xargs -d $'\n' -P 6 -n 16 -- bash -c 'for arg; do download_data "$arg"; done' _ 
+0

ありがとうございました。これは完全に機能するようです。私が80%理解できないコードを使用するのはちょっと痛いですが、あなたのソリューションについて読むのに少し時間を取ることができればうれしいです。 私がこれまでに持っていた問題は、「待機」に関するあなたのコメントに関連していたと思いますか? もう一度、あなたの時間と参考に感謝します。 – Miguel

2

この

cat input.txt | parallel echo link '\#{#} [{}]' 

{#}はジョブ番号
は{}引数

それはCPUごとにプロセスを起動します= =ように見える平行です。あなたが機能を実行することを好む場合

cat input.txt | parallel -j6 echo link '\#{#} [{}]' 

:あなたの代わりに、並列使用-jで6をしたい場合は

download_data(){ 
    echo "link #" $2 "["$1"]" 
} 
export -f download_data 
cat input.txt | parallel -j6 download_data {} {#} 
+0

[cat'の無駄な使い方](http://www.iki.fi/era/unix/award.html)を編集したり、それが悪い習慣であることをどのように知っているか説明してください。しかし、もっと役に立つもののプレースホルダーです。 – tripleee

+0

http://oletange.blogspot.dk/2013/10/useless-use-of-cat.htmlを読んで、それが悪い習慣だと感じた理由を説明してください。 –

+0

私はあなたが思い出すことができると確信しているので、前にこの議論がありました。そのリンクを含めることは、すぐに残っている問題に対する完璧な修正です。そうでなければ、それを1つに見分けることができない読者に反パターンを犯してしまいます。 – tripleee

関連する問題