実行すると(rss-notifierのコードが最後に含まれています)、
rss-notifier.zsh https://www.wuxiaworld.com/feed/chapters ".*"|parallel --null -k --lb echo {}
わかった、
Title: Sovereign of the Three Realms - ????Chapter 1339: Tears Of Joy
Link: https://www.wuxiaworld.com/novel/sovereign-of-the-three-realms/sotr-chapter-1339
Title: Renegade Immortal - Chapter 1259 - Rebuking the Everlasting Sect, Flowing Time
Link: https://www.wuxiaworld.com/novel/renegade-immortal/rge-chapter-1259
Title: Condemning the Heavens - Chapter 242: Three-eyed Troublemaker
Link: https://www.wuxiaworld.com/novel/condeming-the-heavens/cth-chapter-242
Title: Condemning the Heavens - Chapter 241: Join Us
Link: https://www.wuxiaworld.com/novel/condeming-the-heavens/cth-chapter-241
しかし、私が走ると、
rss-notifier.zsh https://www.wuxiaworld.com/feed/chapters ".*"|parallel --null -k --lb -N 2 echo {1} {2}
Parallelはプログラムが最初に終了するのを待つため、何も得られません。
どうすればこの問題を解決できますか? stdinから読み取る2つのnullで区切られた文字列ごとにcommand {1} ... {2}
を並列で実行したいだけです。
これがrss-notifierです:
#!/usr/bin/env zsh
rsstail -l -u "$1" -n 9 | while read -r line1
do
read -r line2
if ggrep -P --silent "$2" <<< "$line1" ; then
printf '%b' "$line1"'\0'"$line2"'\0'
echo
fi
done
または、より単純な再現者の場合:
(printf '%s\0' {1..4}; sleep 2) | parallel --null -k --lb -N 2 echo {1} {2}
更新:ユースケースを実現できる代替ユーティリティにも満足します。 xargsでそれを行う方法は次のとおりですが、あまり優雅ではありません。
あなたは2つの問題に見舞われています。
この
_(seq 200; sleep 20) | parallel -j10 -k echo
_
プリント:
_1
2
_
その後、_sleep 20
_が完了するまでストールします。
部分的な修正は、start_more_jobs()
をwhile
ループの外に移動することのようです。
_--- a/src/parallel
+++ b/src/parallel
@@ -4062,9 +4062,8 @@ sub reaper {
# $stiff = pid of dead process
if(wantarray) {
Push(@pids_reaped,$stiff);
- } else {
- $children_reaped++;
}
+ $children_reaped++;
if($Global::sshmaster{$stiff}) {
# This is one of the ssh -M: ignore
next;
@@ -4112,12 +4111,12 @@ sub reaper {
}
}
$job->cleanup();
- start_more_jobs();
if($opt::progress) {
my %progress = progress();
::status_no_nl("\r",$progress{'status'});
}
}
+ if($children_reaped) { start_more_jobs(); }
$opt::sqlmaster and $Global::sql->run("COMMIT;");
debug("run", "done ");
return wantarray ? @pids_reaped : $children_reaped;
_
短期間の仕事がたくさんある場合、これにはパフォーマンスがいくらかかかる可能性があります。いくら測定していません。
問題の他の部分は、GNU Parallelでの設計上の決定によるものです。
GNU Parallelは、ダイヤモンド演算子(<>)を使用して読み取られます。これにより、続行する前に1行が読み取られます。_(sleep 20)
_からの読み取りでは、sleep
が終了した後にのみファイルの終わりが生成されます。 、したがって、sleep
が終了するまでブロックします。
したがって、GNU Parallelが最後のバイトを読み取るとき、これが実際にファイルの終わりであることを検出するために、sleep
が終了するのを待つ必要があります。
デザインのその部分を変更する簡単な方法はありません。
幸い、date
を実行するとわかるように、これによってジョブの実行がブロックされることはありません。ジョブはすぐに開始されます。sleep
を待機しているのは出力だけです。
_(seq 20; sleep 5) | parallel -j10 -k 'date;echo'
_
言い換えれば、あなたの問題は_-N2
_とは関係ありません。ここでは問題を確認できません。
_(printf '%s\0' {1..4}; sleep 2) | parallel --null -k --lb -N 2 echo {1} {2}
_
しかし、あなたはcanここで問題を確認します。これは、最後の4〜8個の要素の前で一時停止します。
_(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 echo {1} {2}
_
これは、最後の8〜10個の要素の前で一時停止します。
_(printf '%s\0' {1..40}; sleep 2) | parallel -j8 --null -k --lb -N 2 echo {1} {2}
_
date
を実行すると、問題はジョブの開始ではなく、印刷を延期しているだけであることがわかります。
_(printf '%s\0' {1..40}; sleep 2) | parallel -j4 --null -k --lb -N 2 'date;'echo {1} {2}
_