スレッド/パラレルを使用してbashスクリプトを実行する方法

スレッド/パラレルを使用してbashスクリプトを実行する方法

次のbashスクリプトをそのまま実行しています。つまり、順番に進みます。とは、データベースからファイルをダウンロードするための呼び出しprefetchであり、インポートされたファイルを縮小するために作成したC ++プログラムです(制限された記憶領域のため)。fastq-dump_shrink

この機能を実装するためにスレッドを使用できますか?ファイルのダウンロードに時間がかかります。

重要!各ブロック内の命令は順番に実行する必要がありますが、ブロックは並列に実行できます。そして一度に10ブロックだけ実行したいと思います。

#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink

#block1    
prefetch SRR837459
fastq-dump --fasta 0 SRR837459
rm ../../sra_sequences/sra/SRR837459.sra
./_shrink SRR837459
rm SRR837459.fasta
echo "SRR837459" >> list_of_done.txt

#block1    
prefetch SRR805782
fastq-dump --fasta 0 SRR805782
rm ../../sra_sequences/sra/SRR805782.sra
./_shrink SRR805782
rm SRR805782.fasta
echo "SRR805782" >> list_of_done.txt

#... more blocks

答え1

コマンドを並列化する良い方法は次のとおりです。牛に似た一種の栄養parallel。ブロックを関数として定義します。グレンジャックマンが提案したものその後、並列に実行され、-j最大並列実行を定義できます。 Glennのアプローチに比べて利点は、1つのブロックが完了すると新しいブロックが開始されるため、常に10個のブロックが同時に実行されることです。これを表示するには、並列関数をエクスポートする必要があります。

#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink

block() {
  prefetch "$1"
  fastq-dump --fasta 0 "$1"
  ...
}

export -f block

parallel -j 10 block ::: id1 id2 id3 id4 ....

あなたのIDと交換してくださいidi。または類似ファイル(SRR837459など)にIDがある場合

id1
id2
id3

次に、次の行を使用します(他の入力ソースがない場合、GNU Parallelは標準入力から読み取られます)。

parallel -j 10 block

スクリプトを実行して

bash script < idlist.txt

答え2

バックグラウンドで実行するコマンドをグループ化できます。

未テスト

#!/bin/bash
g++ -std=c++11 shrink_files.cpp -o _shrink

block() {
    local id=$1
    prefetch "$id"
    fastq-dump --fasta 0 "$id"
    rm ../../sra_sequences/sra/"$id".sra
    ./_shrink "$id"
    rm "$id".fasta
    echo "$id" >> list_of_done.txt
}

# run first 10 blocks in the background
block SRR837459 &
block SRR805782 &
...
block 10th_id &

# and wait for them to complete
wait

# now start up on the next 10 ...
block 11th_id &
...

または、次のコードがよりプログラム的です。

# all the ids to fetch
ids=( SRR837459 SRR805782 ... )

while (( ${#ids[@]} > 0 )); do
    # copy the first 10 as positional parameters
    set -- "${ids[@]:0:10}"
    # launch the blocks
    for id; do
        block "$id" &
    done
    # wait until done
    wait
    # remove the first 10 from the list
    ids=( "${ids[@]:10}" )
done

関連情報